Bash/sed:没有那个文件或目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47270271/
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
Bash/sed: No such file or directory
提问by Shoreline
I have a script called script.sh:
我有一个名为 script.sh 的脚本:
FILE=
sed -i.bak "s|needle|pin|g" $FILE
If I run it like this:
如果我像这样运行它:
bash ./script.sh /var/www/path/to/file
I get this response:
我得到这个回应:
: No such file or directoryth/to/file
If I run sed
by itself, passing in the same path:
如果我自己运行sed
,则通过相同的路径:
sed -i.bak "s|needle|pin|g" "/var/www/path/to/file"
It works fine (even substituting the values correctly).
它工作正常(甚至正确替换值)。
What am I doing wrong?
我究竟做错了什么?
Bonus observation: I'm assuming it's telling me the entry path is wrong but it's hard to tell because it says ": No such file or directoryth/to/file", which indicates to me that something else is wrong. Maybe something carriage-return related?
额外的观察:我假设它告诉我入口路径是错误的,但很难说,因为它说“:没有这样的文件或目录/到/文件”,这向我表明其他东西是错误的。也许与回车有关?
回答by randomir
You should use quotesaround your variables to prevent word splittingand filename expansion:
file=""
sed -i.bak "s|needle|pin|g" "$file"
(You should also not use all-caps variable namesfor non-environment variables.)
(您也不应该对非环境变量使用全大写的变量名。)
In bash
, each command line (after it has been split in tokens) undergoes a series of shell expansions, in a particular order (emphasis mine):
在 中bash
,每个命令行(在它被分成标记之后)经历一系列的shell 扩展,以特定的顺序(强调我的):
- brace expansion;
- tilde expansion, parameter and variable expansion, arithmetic expansion, process substitution, and command substitution (done in a left-to-right fashion);
- word splitting; and
- filename expansion.
- 大括号扩展;
- 波浪号扩展、参数和变量扩展、算术扩展、进程替换和命令替换(以从左到右的方式完成);
- 分词;和
- 文件名扩展。
So, when you write:
所以,当你写:
file='filename with spaces'
sed "pat" $file
the $file
token will undergo a variable expansion, followed by word splitting, and the command will now look like:
该$file
令牌将进行变量扩展,其次是分词,命令会是这个样子:
sed pat filename with spaces
meaning, sed
received three words for filename, instead of one.
意思是,sed
收到三个词作为文件名,而不是一个。
If you use double quotes, the results of parameter expansion, command substitution, and arithmetic expansion that occurred within the double quotes, are not subjected to word splittingand filename expansion. In our example:
如果使用双引号,则双引号内发生的参数扩展、命令替换和算术扩展的结果不会受到分词和文件名扩展的影响。在我们的例子中:
file='filename with spaces'
sed "pat" "$file"
is expanded to:
扩展为:
sed "pat" "filename with spaces"
with spaces in filename preserved.
保留文件名中的空格。
回答by J. Anderson
there must have some unprintable control character in your path string variable, you could print the content of it with declare -p
:
您的路径字符串变量中必须有一些不可打印的控制字符,您可以使用以下命令打印它的内容declare -p
:
FILE=
declare -p FILE