我想在 zsh 中运行为 bash 编写的脚本。
如果我跑哪个 bash,我得到
/usr/bin/bash
按照此回答我已经创建了以下脚本
#!/usr/bin/bash
echo 'Hello'
文件你好在目录中〜/.scriptsPATH 变量是
~/.scripts: ...
hello 的定义是
rwxr-xr-x 1 jeff jeff 30 Nov 21 15:04 hello
在 bash 中我运行
$ hello
并且它工作正常
在 zsh 中如果我运行
% hello
我得到了错误
zsh:未找到命令:你好
但在 zsf 中如果我运行
% bash hello
它工作正常
怎么了?
答案1
您的 中的文字波浪号PATH
由 Bash 扩展,但由 Zsh 扩展。通常您不应该~
在 中使用PATH
。请使用完整路径。
在赋值中,波浪符前缀可以放在单词开头(即=
赋值的后面)和/或任何未加引号的 后面:
;波浪符将在赋值时展开,不会PATH
以文字形式出现。这是故意让这种语法
PATH=~/.scripts:"$PATH"
即使使用 的任何内容稍后PATH
都不会扩展,它也能正常工作~
。关键是将不会扩展;首先~
将有已经扩展的路径,而不是波浪号。PATH
但是语法是这样的:
PATH="~/.scripts:$PATH"
使用文字波浪号创建PATH
。Bash 在运行时会扩展波浪号,而 Zsh 则不会。
修复 的定义PATH
,使其不包含任何波浪符号。echo $PATH
应该打印/home/psionman/.scripts:…
左右。
答案2
您不仅需要创建脚本,还需要使其可执行。然后,当您运行它时,该#!
行将指示系统在哪里找到代码的解释器。
示例:
cat >demo <<'EOF' # Reads lines into the file "demo" until "EOF"
#!/usr/bin/bash
echo 'Hello from a script run by bash'
EOF
chmod a+rx demo # Make the script available (readable and executable) for everyone
./demo # Run it
输出
Hello from a script run by bash
请注意,作为用户(而不是程序员),您不需要指定解释器在命令行上运行脚本 - 您绝对不需要知道它是为其编写的bash
。
您需要./demo
并且 而不仅仅是demo
。这是因为 UNIX/Linux 和 Mac 系统(与 Windows 不同)通常不将当前目录 ( .
) 包含在搜索程序的位置集合中。搜索的目录集合在变量中指定$PATH
为冒号分隔的列表。
如果您有/usr/local/bin
该列表中的文件,并且将demo
文件移动到该目录,则可以像运行demo
任何其他系统程序一样运行。同样,如果您有$HOME/bin
目录,也可以将其放在那里。请注意,不一定是您的目录的~
有效指示符。它对 POSIX shell(包括和)有效,但在其他地方无效:$PATH
$HOME
bash
zsh
mkdir -p "$HOME/bin" # Or for many shells, mkdir -p ~/bin
PATH="$HOME/bin:$PATH" # Acceptable everywhere
PATH=~/bin:"$PATH" # Acceptable if set by a shell that handles ~
PATH="~/bin:$PATH" # Invalid almost everywhere (works for bash, fails for zsh)
在前两个赋值示例中,$HOME
和~
由 shell 扩展,结果$PATH
具有一组显式的具体目录路径。在第三个赋值中,第一个目录路径仍然是~/bin
,虽然它可以被理解bash
,但执行程序所需的其他所有东西可能都无法理解它。这里的解决方案是修复您对赋值的双引号(不要~
在双引号内)。