bash 脚本中的单引号

bash 脚本中的单引号

我的命令语法为

command 'variable'

该变量必须用单引号传递。

现在,当我使用带有输入文件的 for 循环时

variable1
variable2
variable3

for i in `cat $1`
do
       command '$i'
done

shell>file.sh input

单引号不完整,因为 bash 不将输入作为变量 请建议如何使用单引号保持变量完整

答案1

任何用单引号括起来的内容都将按照您键入的内容准确传递。因此会将由两个字符和command '$i'组成的字符串传递给命令。$i

您应该使用双引号来获取所使用的变量值

for i in `cat $1`
do
       command "$i"
done

或者,由于您的代码需要文件中每行一个单词,因此用这一行替换整个循环:

xargs -n1 -r command <"$1"

答案2

这可能会按照要求进行:

while read i
do
       command "'$i'"
done < "$1"

答案3

如果您想调用command文件的每一行(其路径存储在 中$1),并将该行的内容逐字作为单个参数传递给command,那么您可以使用:

  • 使用 GNU xargs

    xargs -d '\n' -n 1 -r -a "$1" command
    
  • 使用 POSIX shell:

    while IFS= read -r line <&3; do
      command "$line" 3<&-
    done 3< "$1"
    

你的

for i in `cat $1`; do
  command '$i'
done

除了传递文字$i字符串这一明显问题之外,command还有其他几个问题:

  • 您忘记引用$1,这意味着它受到 split+glob 的影响,这意味着它对于包含空格、制表符、换行符或通配符的文件路径无法正常工作
  • 您忘记了--标记选项的结尾,cat这意味着它对于以 . 开头的文件路径无法正常工作-。即使使用cat -- "$1",它也不适用于名为-.cat < "$1"会更好。请注意,如果您command 也接受选项,您可能还需要使用--(xargs ... command --command -- "$line")
  • `cat $1`会再次调用 split+glob 运算符。因此,它不是循环遍历文件的行,而是循环遍历与文件内容分割产生的每个 glob 模式相匹配的文件列表。

答案4

您可以使用不带引号的命令:

for i in `cat $1`
do
       command $i
done

使用单引号'$i':您会得到字面意思$i

使用双引号"$i":您可以获取 中的值$i,但作为单个字符串(这通常是所需的行为)。

不带引号$i:这将扩展为 中的值$i,但参数会被分割。因此,如果你有一个空格,例如-a -b,带有双引号,你就会有一个-a -b通常不期望的参数,但在最后一种情况下,你将有-a-b作为两个不同的参数。

我应该建议您,不使用引号通常是一个安全问题,因此只有在您确实知道输入不是恶意的情况下才应该这样做。

相关内容