Bash / sed:没有这样的文件或目录

时间:2017-11-13 17:36:20

标签: bash sed

我有一个名为script.sh的脚本:

FILE=$1
sed -i.bak "s|needle|pin|g" $FILE

如果我这样运行:

bash ./script.sh /var/www/path/to/file

我收到了这个回复:

: No such file or directoryth/to/file

如果我自己运行sed,则传递相同的路径:

sed -i.bak "s|needle|pin|g" "/var/www/path/to/file"

它工作正常(甚至正确地替换了值)。

我做错了什么?

奖金观察:我假设它告诉我输入路径错误但很难说,因为它说“:没有这样的文件或目录/ /文件”,这对我来说别的东西是错的。也许马车回归有关?

2 个答案:

答案 0 :(得分:2)

您应该在变量周围使用引号来阻止word splittingfilename expansion

file="$1"
sed -i.bak "s|needle|pin|g" "$file"

(对于非环境变量,您还应该not use all-caps variable names。)

bash中,每个命令行(在它被分成标记之后)经历了一系列shell expansions,按特定顺序(强调我的):

  
      
  • 支撑扩张;
  •   
  • 代码扩展,参数和变量扩展,算术扩展,进程替换和命令替换(以从左到右的方式完成);
  •   
  • 分词;和
  •   
  • 文件名扩展
  •   

所以,当你写:

file='filename with spaces'
sed "pat" $file

$file令牌将经历变量扩展,然后是分词,现在该命令将如下所示:

sed pat filename with spaces

意思是,sed收到了三个用于文件名的单词,而不是一个单词。

如果使用双引号,则在双引号内发生的参数扩展,命令替换和算术扩展的结果不会受分词和< em>文件名扩展。在我们的例子中:

file='filename with spaces'
sed "pat" "$file"

扩展为:

sed "pat" "filename with spaces"

保留文件名中的空格。

答案 1 :(得分:1)

路径字符串变量中必须有一些不可打印的控制字符,您可以使用declare -p打印它的内容:

FILE=$1
declare -p FILE