gpt4 book ai didi

linux - 在 shell 脚本中执行命令时在双引号内转义单引号

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:34:50 32 4
gpt4 key购买 nike

function install_rubygems {
#install rubygems
ruby_cmd=("sudo gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3"
"bash -c 'curl -sSL https://get.rvm.io|bash -s stable'"
"source /etc/profile.d/rvm.sh"
#"rvm install 1.9.2 --with-zlib-directory=/usr/local/rvm/usr --with-openssl-directory=/usr/local/rvm/usr"
#"rvm --default use 1.9.2"
#"gem install soap4r-ruby1.9 log4r net-ldap json httpclient"
)
for cmd in "${ruby_cmd[@]}"
do
$cmd
exit_status=$?
if [ "$exit_status" -ne "0" ]; then
echo "Error occured while running: $cmd. Exiting..."
exit
fi
done
}

我想一个一个地执行 ruby​​_cmd 数组中列出的命令,然后检查每个命令的退出状态,然后执行一些操作。但是当我在 shell 中执行上面的脚本时,它给出了如下错误:

-sSL: -c: 第 0 行:在寻找匹配的“”时出现意外的 EOF-sSL: -c: 第 1 行:语法错误:文件意外结束

我是 shell 脚本的新手,谁能告诉我上面命令的正确写法是什么?PS:命令正确,直接在bash上运行可以正常执行

最佳答案

有关该主题的一般性讨论,请参阅 BashFAQ #50 .

有几种方法可用:

使用函数

install_rubygems() {
sudo gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 && \
curl -sSL https://get.rvm.io | bash -s stable && \
source /etc/profile.d/rvm.sh
)

install_rubygems || {
retval=$?
echo "Error occurred while running; exiting..." >&2
exit "$retval"
}

使用可求值数组

如果您的所有字符串都不能包含用户输入,那么这是安全的。否则,它会让您遭受 shell 注入(inject)攻击。

install_rubygems=(
"sudo gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3"
"curl -sSL https://get.rvm.io | bash -s stable"
"source /etc/profile.d/rvm.sh"
)
for cmd in "${install_rubygems[@]}"; do
eval "$cmd" || {
retval=$?
echo "Error occurred while running $cmd; exiting..." >&2
exit "$retval"
}
done

使用多个单命令数组

因为这里的每个数组只有一个简单的命令——没有管道,没有间接,没有在评估时执行的替换——它比 eval 方法更安全:只在明确的地方通过扩展运行代码(如 bash -c 的参数或显式 eval 的参数)容易出现未定义的行为,因此您可以在其他位置安全地使用不受信任的数据(例如作为 --keyserver 的参数)确信 shell 不会对它做任何不利的事情,即使该数据正在尝试 shell 注入(inject)攻击。

install_rubygems_01=( sudo gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 )
install_rubygems_02=( eval 'curl -sSL https://get.rvm.io | bash -s stable' )
install_rubygems_03=( source /etc/profile.d/rvm.sh )

for varname in "${!install_rubygems_@}"; do

# there's a safer way to do this in bash 4.3, but that's not widely deployed yet
# (this particular command shouldn't ever be unsafe unless varname has been tampered
# with, but it had to be constructed very carefully).
eval "cmd=( \"\${$varname[@]}\" )"

## ...specifically, in bash 4.3, you could do this instead of the above eval:
#declare -n cmd=$varname

# evaluate array as an exact argv
"${cmd[@]}" || {
retval=$?
printf -v cmd_str '%q ' "${cmd[@]}"
echo "Error occurred while running ${cmd_str% }; exiting..." >&2
exit "$retval"
}

##Using bash 4.3 namevars instead of the eval above, you'd want to do this here:
#unset -n cmd
done

关于linux - 在 shell 脚本中执行命令时在双引号内转义单引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37616355/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com