我计划改用 Fish 作为我的默认 shell,但遇到了一些麻烦。
在重写我的所有脚本之前,我想使用带有“-c”选项的 bash 重用旧脚本。
示例:
bash -c "cat <<'EOF' | tee filename >/dev/null
$SHELL
$TERM
EOF"
即使使用
'EOF'
,我总是得到:/bin/fish
xterm
如果可能,我想避免在脚本中的每个变量中使用反斜杠
\$SHELL
。
这里的主要问题是 $SHELL 的含义并不像您想象的那样。
$SHELL 不是“当前运行的 shell”,它是“用户配置的登录 shell”。
bash 和 Fish(也不是 zsh)都不会设置它,它们会从您的登录堆栈继承它。
这意味着您正在尝试做的事情不会起作用。
下一步是将参数“fish”用双引号括起来:
bash -c "..."
这意味着其中的变量将被扩展。您可以单引号它们:
bash -c '...'
这意味着您需要转义参数中的任何单引号,例如
bash -c 'cat <<\'EOF\' | tee filename >/dev/null
$SHELL
$TERM
EOF'
当然这会告诉 bash 去做
cat <<'EOF' | tee filename >/dev/null
$SHELL
$TERM
EOF
这意味着it也不会扩展变量。您可以使用不带引号的
EOF
让 bash 扩展变量。
这看起来不会有任何不同,因为(见上文)$SHELL 在两个 shell 之间不会改变。您可以使用仅在 bash 中设置的变量来确认其正常工作:
bash -c 'cat <<EOF | tee filename >/dev/null
$BASH_VERSION
$TERM
EOF'
这将为您提供“文件名”中的 bash 版本。
嵌套引用和转义以及哪个 shell 扩展哪个变量的问题是我通常建议只编写 bash 脚本的原因。
创建一个名为“printshell.sh”的文件,其中包含以下内容:
#!/bin/bash
cat <<EOF | tee filename >/dev/null
$SHELL
$TERM
EOF
使其可执行(
chmod +x
)并将其放在 $PATH 中的某个位置。如果您没有合适的目录,您可以创建一个 (mkdir
) 并使用 fish_add_path
将其添加到 Fish 的 $PATH 中。