gsi*_*011 11 linux cygwin bash
假设我想将以下命令存储在一个变量中
cd "/cygdrive/c/Program Files/"
Run Code Online (Sandbox Code Playgroud)
所以我这样做
dir="cd \"/cygdrive/c/Program Files/\""
Run Code Online (Sandbox Code Playgroud)
那应该存储导航到 Program Files 目录的命令,所以当我输入 $dir 时,它会将我带到该目录。要检查引号是否已正确转义,我键入
echo $dir
Run Code Online (Sandbox Code Playgroud)
这给了我
cd "/cygdrive/c/Program Files/"
Run Code Online (Sandbox Code Playgroud)
所以一切都应该正常工作。然而,当我打字时,
$dir
Run Code Online (Sandbox Code Playgroud)
我得到
bash: cd: "/cygdrive/c/Program: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我正在使用 Cygwin,但我认为这个问题一般适用于 bash。
简短回答:请参阅BashFAQ #050(“我正在尝试将命令放入变量中,但复杂的情况总是失败!”)。
长答案:当 bash 解析命令时,它会在替换变量之前解析引号;它永远不会返回并重新解析变量值中的引号,因此它们最终没有做任何有用的事情。使用 echo 检查命令完全具有误导性,因为它在解析后显示命令;如果您想查看真正执行的内容,请使用在执行时set -x
让 shell 打印命令,或者使用printf "%q " $dir; echo
而不是普通的 echo。
如果你想存储一个复杂的命令(即“单词”中有空格或其他特殊字符的命令),你需要把它放在一个数组中而不是一个简单的文本变量中,然后用习语`"${展开它数组[@]}”,像这样:
dir=(cd "/cygdrive/c/Program Files/")
"${dir[@]}"
Run Code Online (Sandbox Code Playgroud)
现在,如果目的是制作易于键入的速记,这显然不是要走的路。改用 shell 别名或函数:
alias dir='cd "/cygdrive/c/Program Files/"'
dir
Run Code Online (Sandbox Code Playgroud)
或者
dir() { cd "/cygdrive/c/Program Files/"; }
dir
Run Code Online (Sandbox Code Playgroud)
当 bash expand 时$dir
,它只对它执行分词和通配符。分词产生三个词:cd
,"/cygdrive/c/Program
和Files/"
。那么要执行的命令cd
有两个参数;cd
只查看它的第一个参数,"/cygdrive/c/Program
,它不是一个现有的目录。
如果要对变量的内容执行完整的 shell 评估,请使用eval
:
eval "$dir"
Run Code Online (Sandbox Code Playgroud)
请注意,您需要在 周围加上双引号$dir
,否则将首先执行分词,然后eval
将其参数与空格连接起来。这会在这里工作,但通常会变坏(例如,如果文件名中有两个连续的空格)。
但是,字符串不是存储要执行的 shell 命令的正确方法。除非您有不寻常的需求,否则您应该使用函数:
dir () {
cd "/cygdrive/c/Program Files/"
}
Run Code Online (Sandbox Code Playgroud)
如果您真的有兴趣键入$dir
以切换到特定目录,这不仅仅是一个简单的示例,因为 bash 4,请shopt -s autocd
输入您的.bashrc
并设置
dir="/cygdrive/c/Program Files/"
Run Code Online (Sandbox Code Playgroud)
之后,您可以在 shell 提示符下键入"/cygdrive/c/Program Files/"
或"$dir"
以切换到该目录。你仍然需要双引号$dir
; 如果您不喜欢那样,请使用 zsh 而不是 bash。
将命令存储在变量中通常不是一个好主意。这就是函数和别名的用途。
而不是
dir="cd \"/cygdrive/c/Program Files/\""
Run Code Online (Sandbox Code Playgroud)
尝试其中之一:
dir="/cygdrive/c/Program Files"
...
cd "$dir"
Run Code Online (Sandbox Code Playgroud)
或者
dir() { cd "/cygdrive/c/Program Files"; }
dir
Run Code Online (Sandbox Code Playgroud)
或者
alias dir='cd "/tmp/Program Files"'
...
dir
Run Code Online (Sandbox Code Playgroud)
第一种形式,将目录的名称存储在变量中,意味着需要输入更多内容,但是当您执行正在执行的命令时,它会更清晰cd
。第二个最接近你想要完成的。(我在 bash 中很少使用别名;我实际上不确定它们比函数有什么优势。)
编辑 :
并且dir
对于别名或函数来说可能是一个不好的名字,因为有一个同名的现有命令(它基本上是 的一个版本ls
,至少如果你有 GNU coreutils)。
归档时间: |
|
查看次数: |
12722 次 |
最近记录: |