命令在Shell中正常工作,但在使用脚本时不能

时间:2016-01-16 23:30:09

标签: bash shell scripting

我在Bash Shell中使用了这个命令:

printf $VAR1 >> `printf $VAR2`

它通常有效。但是当我将其写入脚本文件并在Shell中运行时,它不起作用。文件“script.sh”包含:

#!/bin/bash
printf $VAR1 >> `printf $VAR2`

,Shell中的输出是:

script.sh: line2: `printf $VAR2`: ambiguous redirect

我不知道,这怎么可能,因为命令完全相同。当然,我在同一个系统和同一个Shell窗口中运行脚本。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

这里有三点值得讨论:

Shell变量与环境变量:

  • 脚本(除非使用. / source调用)在进程中运行,该进程只能看到父[shell]' s environment 变量,而不是常规 shell 变量。

    • OP的情况可能发生了这种情况:$VAR1$VAR2作为常规 shell 变量存在,但不是环境变量,因此脚本script.sh没有看到它们。
  • 因此,要让子进程看到父shell的shell变量,父进程必须首先 export ,结果它们(也)成为环境变量:export VAR1=... VAR2=...

Bash与输出重定向相关的错误消息(>>>

  • 如果输出重定向的文件名参数是 - 未加引号 command substitution`...`,或其现代等价物,$(...)) - 即,命令的输出 - Bash在以下情况下报告错误ambiguous redirect

    • 命令输出嵌入了空格,即包含多个单词
    • 命令输出为空,这可能是在OP的情况下发生的。
      • 顺便说一句:在这种情况下,错误信息的措辞是不幸的,因为没有任何关于缺少文件名的模糊 - 它根本无法工作,因为文件需要名称。
  • 一般建议双引号命令替换(例如>> "$(...)")以及变量引用(例如"$VAR2"):这将允许你返回带有嵌入空格的文件名,如果输出意外为空,您将得到(稍微)更有意义的错误消息No such file or directory

    • 双引号变量引用或命令替换将其值/置于所谓的shell expansions:进一步,通常是shell无意识的解释。

使用命令替换生成文件名的智慧

暂且不说printf $VAR2一般是打印变量$VAR2的值的脆弱方式(强健形式再次涉及双引号:printf "$VAR2",或者更强大,为了排除对变量值printf %s "$VAR2")中的转义序列的无意解释,如果所需要的只是一个,则没有充分的理由采用命令替换来开始变量的值:

>> "$VAR2"足以可靠地将变量$VAR2的值指定为目标文件名。

答案 1 :(得分:-2)

我在Mac(10.11.1)的终端窗口中尝试了这个,它工作正常。

你确定你的默认shell是bash吗?

echo $SHELL

您是否使用EXPORT设置shell变量?

$ export VAR1="UselessData"
$ export VAR2="FileHoldingUselessData"
$ ./script.sh
$ cat FileHoldingUselessData
UselessData$

然而......回声我觉得做得更好,因为使用printf输出终止于第一个空格所以....

$ cat script.sh
#!/bin/bash
echo $VAR1 >> `printf $VAR2`

$ ./script.sh
$ cat FileHoldingUselessData
Some Useless Data

这让我相信你可能只想使用echo而不是printf ..

#!/bin/bash
echo $VAR1 >> `echo $VAR2`