批处理文件中的多行变量,在打印机权限脚本中回显隐藏的空格。

huangapple go评论77阅读模式
英文:

Multi line variable in batch file echoing back hidden spaces in printer permission script

问题

我几小时前坐下来写了一行或两行代码,看起来似乎很简单,可以使用WMIC和subinacl.exe的组合来为计算机上的每个打印队列添加权限。

@echo off
pushd %~dp0
setlocal EnableDelayedExpansion
for /f "skip=1 tokens=*" %%a in ('wmic printer get name') do (
    set "_var=%%a" 
    for /f "tokens=1,* delims=" %%g in ("!_var!") do (
        echo subinacl /printer "%%g" /grant=Everyone=F
    )
)
pause

结果发现这并不那么容易!这是我能做到的最接近的工作方式,但是回显显示额外的空格和引号放错了位置,导致subinacl在打印机名称错误的情况下失败,以下是输出:

subinacl /printer "Canon MG5300 series Printer WS  " /grant=Everyone=F
subinacl /printer "testfff                         " /grant=Everyone=F
subinacl /printer "OneNote (Desktop)               " /grant=Everyone=F
subinacl /printer "Microsoft Print to PDF          " /grant=Everyone=F
subinacl /printer "Canon MG5300 series Printer     " /grant=Everyone=F
subinacl /printer "444444444444444                 " /grant=Everyone=F
Press any key to continue . . .

应该如下所示,以使subinacl正确应用权限:

subinacl /printer "Canon MG5300 series Printer WS" /grant=Everyone=F
subinacl /printer "testfff" /grant=Everyone=F
subinacl /printer "OneNote (Desktop)" /grant=Everyone=F
subinacl /printer "Microsoft Print to PDF" /grant=Everyone=F
subinacl /printer "Canon MG5300 series Printer" /grant=Everyone=F
subinacl /printer "444444444444444" /grant=Everyone=F
Press any key to continue . . .

如何修改我的脚本以实现正确的间距和引号,像上面所示。我相信我应该能够做到这一点,没有问题,但我漏掉了什么 - 可能是显而易见的。

我有一种感觉,这与将解析的WMIC输出作为一个变量在一个块中设置有关,也许每个变量的每一行(打印队列)都需要单独发送到subinacl命令中。

通常在这些情况下,我可以达到我想要的目标,但无法解决这个问题。对任何指针将不胜感激。谢谢!

英文:

I sat down hours ago to write a seemingly straight forward 1 or 2 liner to add permissions to every print queue on a computer using a combination of WMIC and subinacl.exe.

@echo off
pushd %~dp0
setlocal EnableDelayedExpansion
for /f "skip=1 tokens=*" %%a in ('wmic printer get name') do (
set "_var=%%a" do (
for /f "tokens=1,* delims=" %%g in ("!_var!") do (
echo subinacl /printer "%%g" /grant=Everyone=F
	)
)
pause

Turns out it aint so easy at all! This is as close to working I can get, but the echoing reveals extra spaces and quotations in the wrong places, causing sunbinacl to fail with printer name errors, this is the output: -

subinacl /printer "Canon MG5300 series Printer WS  " /grant=Everyone=F
subinacl /printer "testfff                         " /grant=Everyone=F
subinacl /printer "OneNote (Desktop)               " /grant=Everyone=F
subinacl /printer "Microsoft Print to PDF          " /grant=Everyone=F
subinacl /printer "Canon MG5300 series Printer     " /grant=Everyone=F
subinacl /printer "444444444444444                 " /grant=Everyone=F
Press any key to continue . . .

This is how it should look for subincal to correctly apply the permissions...

subinacl /printer "Canon MG5300 series Printer WS" /grant=Everyone=F
subinacl /printer "testfff" /grant=Everyone=F
subinacl /printer "OneNote (Desktop)" /grant=Everyone=F
subinacl /printer "Microsoft Print to PDF" /grant=Everyone=F
subinacl /printer "Canon MG5300 series Printer" /grant=Everyone=F
subinacl /printer "444444444444444" /grant=Everyone=F
Press any key to continue . . .

How can I alter my script to achieve the correct spacing and quotations around the printer name like above. I believe I should be able to do this, no problem, but I'm missing something - probably obvious.

I have a feeling it has to do with taking the parsed WMIC output being set as a variable in one block, where perhaps each line of the variable (printer queue) needs to be sent into the subinacl command one by one.

Usually I can get to where I want to be in these instances but cant surpass this issue. Any pointers would be greatly appreciated. Thanks

答案1

得分: 2

这是因为 wmic 会将字符串格式化为一个漂亮的表格输出,通过用空格填充过短的字符串。

很容易避免。只需更改格式。

... ('wmic printer get name') ... 更改为

... ('wmic printer get name /format:list') ...

你不需要设置一个变量来在内循环中使用,你可以直接使用外循环的元变量(尽管你需要第二个循环来摆脱丑陋的 wmic 格式,带有一个 CRCRLF 行结束符。还有其他方法,但 for 循环是最通用和最安全的):

@echo off
pushd %~dp0
setlocal 
for /f "tokens=1* delims==" %%a in ('wmic printer get name /format:list ^|find "="') do (
  for /f "tokens=1,* delims=" %%g in ("%%b") do (
    echo subinacl /printer "%%g" /grant=Everyone=F
  )
)
英文:

This is because wmic formats the strings for a nice table output on screen by filling too short strings with spaces.

Easy to avoid. Just change the formatting.

Change ... ('wmic printer get name') ... to

... ('wmic printer get name /format:list') ...

You don't need to set a variable to use in the inner loop, you can just use the metavariable from the outer loop (you need the second loop though to get rid of the ugly wmic format with a CRCRLF line ending. There are other methods, but a for loop is the most general and safest):

@echo off
pushd %~dp0
setlocal 
for /f "tokens=1* delims==" %%a in ('wmic printer get name /format:list ^|find "="') do (
  for /f "tokens=1,* delims=" %%g in ("%%b") do (
    echo subinacl /printer "%%g" /grant=Everyone=F
  )
)

答案2

得分: 0

[未测试]

...
  for /f "tokens=1,* delims=" %%g in ("!_var!") do (
  set "_printer=%%g"
  call :trim
  echo subinacl /printer "!_printer!" /grant=Everyone=F
    )
)
pause

goto :eof

:trim
if "%_printer:~-1%"==" " set "_printer=%_printer:~0,-1%"&goto trim
goto :eof
  • 将打印机名称分配给 _printer 并将 :trim 执行为子程序(因此有 goto :eof,它防止流经到子程序)。

:trim 简单地检查 _printer 的最后一个字符,如果是空格,则删除它,并重复此操作,直到删除尾随的空格。

重复:未测试

英文:

[untested]

...
  for /f "tokens=1,* delims=" %%g in ("!_var!") do (
  set "_printer=%%g"
  call :trim
  echo subinacl /printer "!_printer!" /grant=Everyone=F
    )
)
pause

goto :eof

:trim
if "%_printer:~-1%"==" " set "_printer=%_printer:~0,-1%"&goto trim
goto :eof
  • assign printername to _printer and execute :trim as a subroutine (hence the goto :eof which prevents flow-through to the subroutine)

:trim simply checks the last character of _printer and if it is a space, trims it off and repeats the operation until the trailing spaces are gone.

Repeat : untested

答案3

得分: 0

为了满足您的[tag:cmd]标签和一两行的要求,这里有一个单行示例,可以直接在命令提示符(cmd.exe)窗口中运行:

for /f tokens^=6^ delims^=^" %g in ('wmic printer get name /format:mof 2^>nul') do @subinacl /printer "%g" /grant=everyone=F

但是,为了编写健壮且高效的代码,您应该使用完全限定和绝对路径,包括扩展名,来指定您的可执行工具。

英文:

To fulfil your [tag:cmd] tag, and one or two liner requirements, here's a single line example which can be run directly in a Command Prompt, (cmd.exe), window:

for /f tokens^=6^ delims^=^" %g in ('wmic printer get name /format:mof 2^>nul') do @subinacl /printer "%g" /grant=everyone=F

For robust and efficient code, you should, however, use the fully qualified and absolute paths, with extensions, for both of your executable utilities.

huangapple
  • 本文由 发表于 2023年7月13日 10:56:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76675601.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定