Bash、Fish:防止变量扩展

问题描述 投票:0回答:1

我计划改用 Fish 作为我的默认 shell,但遇到了一些麻烦。
在重写我的所有脚本之前,我想使用带有“-c”选项的 bash 重用旧脚本。
示例:

bash -c "cat <<'EOF' | tee filename >/dev/null
$SHELL
$TERM
EOF"

即使使用

'EOF'
,我总是得到:
/bin/fish

xterm

如果可能,我想避免在脚本中的每个变量中使用反斜杠

\$SHELL

shell variables fish expansion
1个回答
0
投票

这里的主要问题是 $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 中。

© www.soinside.com 2019 - 2024. All rights reserved.