bash 变量替换后防止通配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10452107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:11:48  来源:igfitidea点击:

Prevent globbing after variable substitution

bashshellescapingglob

提问by fungs

What is the most elegant way to use shell variable (BASH) that contain characters reserved for globbing (filename completion) that trigger some unwanted substitutions? Here is the example:

使用包含为通配符(文件名完成)保留的字符的 shell 变量 (BASH) 的最优雅方法是什么?这是示例:

for file in $(cat files); do
   command1 < "$file"
   echo "$file"
done

The file names contain characters like '[' or ']'. I have basically two ideas:

文件名包含诸如“[”或“]”之类的字符。我基本上有两个想法:

1) Turn off globbing via set -f: I need it somewhere else

1)通过 set -f 关闭通配:我在其他地方需要它

2) Escape the file names in files: BASH complains about "file not found" when piping into stdin

2) 转义文件中的文件名:BASH 在管道输入标准输入时抱怨“找不到文件”

Thx for any suggestion

感谢任何建议

Edit: The only answer missing is how to read from a file with name containing special characters used for globbing when the filename is in a shell variable "$file", e. g. command1 < "$file".

编辑:唯一缺少的答案是当文件名位于 shell 变量“$file”中时,如何从名称包含用于通配符的特殊字符的文件中读取,例如 command1 <“$file”。

回答by tilo

As an alternative to switching between set -fand set +fyou could perhaps just apply a single set -fto a subshell since the environment of the parent shell would not by affected by this at all:

作为在set -f和之间切换的替代方法,set +f您也许可以将单个set -f应用于子外壳,因为父外壳的环境根本不会受此影响:

(
set -f
for file in $(cat files); do
   command1 < "$file"
   echo "$file"
done
)


# or even

sh -f -c '
   for file in $(cat files); do
      command1 < "$file"
      echo "$file"
   done
'

回答by Emil

You can turn off globbing with set -f, then turn it back on later in the script with set +f.

您可以使用 关闭通配set -f,然后在脚本中稍后使用 将其重新打开set +f

回答by clyfish

Use while readinstead.

使用while read来代替。

cat files | while read file; do
    command1 < "$file"
    echo "$file"
done