Bash - 如何避免命令“eval set --”评估变量

2024-04-08

我只是编写了一个小 bash 脚本来管理多个并行 ssh 命令。 为了解析参数,我使用这段代码:

#!/bin/bash

# replace long arguments
for arg in "$@"; do
    case "$arg" in
        --help)           args="${args}-h ";;
        --host|-hS)       args="${args}-s ";;
        --cmd)            args="${args}-c ";;
        *) [[ "${arg:0:1}" == "-" ]] && delim='' || delim="\""
           args="${args}${delim}${arg}${delim} ";;
    esac
done

echo "args before eval : $args"
eval set -- $args
echo "args after eval  : $args"

while getopts "hs:c:" OPTION; do
    echo "optarg : $OPTARG"
    case $OPTION in
    h)  usage; exit 0;;
    s)  servers_array+=("$OPTARG");;
    c)  cmd="$OPTARG";;
    esac
done

所以我可以使用 -s、--host 或 -hS 来获得相同的结果。 除了一件事之外,一切都很好。

如果我将一个变量放入参数中,它将被评估。

说明

./test.sh -s SERVER -c 'echo $HOSTNAME'
  1. cmd应分配给echo $HOSTNAME但由于eval setcmd 实际上被分配给echo server1(变量的值)

  2. 如果我评论该行eval set -- $args我不能使用长选项(--cmd)但是cmd被分配给echo $HOSTNAME正如预期的那样

有没有解决方案可以避免 eval set / getopts 来评估变量? 因此具有与 2. 相同的行为,但有很长的可用选项。

Examples

与评估集

./test.sh -s SERVER -c 'echo $HOSTNAME'
args before eval : -s "SERVER" -c "echo $HOSTNAME"
args after eval  : -s "SERVER" -c "echo $HOSTNAME"
optarg : SERVER
optarg : echo server1

没有评估集(行eval set -- $args评论)

./test.sh -s SERVER -c 'echo $HOSTNAME'
args before eval : -s "SERVER" -c "echo $HOSTNAME"
args after eval  : -s "SERVER" -c "echo $HOSTNAME"
optarg : SERVER
optarg : echo $HOSTNAME

正如你所注意到的,eval is evil http://mywiki.wooledge.org/BashFAQ/048——这里没有必要使用它。

#!/bin/bash

# make args an array, not a string
args=( )

# replace long arguments
for arg; do
    case "$arg" in
        --help)           args+=( -h ) ;;
        --host|-hS)       args+=( -s ) ;;
        --cmd)            args+=( -c ) ;;
        *)                args+=( "$arg" ) ;;
    esac
done

printf 'args before update : '; printf '%q ' "$@"; echo
set -- "${args[@]}"
printf 'args after update  : '; printf '%q ' "$@"; echo

while getopts "hs:c:" OPTION; do
    : "$OPTION" "$OPTARG"
    echo "optarg : $OPTARG"
    case $OPTION in
    h)  usage; exit 0;;
    s)  servers_array+=("$OPTARG");;
    c)  cmd="$OPTARG";;
    esac
done

也就是说:构建命令行时,将各个项目追加到数组中;然后,您可以扩展该数组(带引号),而不会因字符串分割、全局扩展等的影响而冒评估或不良行为的风险。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Bash - 如何避免命令“eval set --”评估变量 的相关文章

  • 自动检测log4j静态初始化错误的方法

    请注意 这更像是 Bash 问题 而不是 Java 问题 请参阅下面的注释 在每个类中配置log4j时 我们执行以下操作 public class Example private static final Logger log Logger
  • Python 用静态图像将 mp3 转换为 mp4

    我有x文件包含一个列表mp3我想转换的文件mp3文件至mp4文件带有static png photo 似乎这里唯一的方法是使用ffmpeg但我不知道如何实现它 我编写了脚本来接受输入mp3文件夹和一个 png photo 然后它将创建新文件
  • 从 Ruby 运行 shell 命令:在显示输出时捕获输出?

    我有个问题 我想从另一个 ruby 脚本运行一个 ruby 脚本并捕获它的输出信息 同时让它也输出到屏幕上 runner usr bin env ruby print Enter your password password gets ch
  • CentOS目录结构是树形的吗?

    CentOS 上有相当于树的东西吗 如果你的 Centos 系统上没有安装 tree 无论如何我通常建议服务器设置使用最小安装磁盘 你应该在命令行中输入以下内容 yum install tree y 如果没有安装 那是因为您没有正确的存储库
  • BASH 脚本编译多个 C++ 文件 - OpenCV

    请参见在C 和OpenCV中调用其他文件中的函数 https stackoverflow com questions 24442836 call functions in other files in c and opencv 对于最初的问
  • 为什么 Windows 批处理文件“exit”不能与“||”一起使用?

    批处理 命令脚本中的通常建议是使用exit b设置时退出ERRORLEVEL来指示错误 然而这与 CMD 的配合不太好 and 运营商 如果我在 CMD 命令行运行这些 C gt echo exit b 1 gt foo cmd C gt
  • 如何在 bash 中结合超时和 eval 命令

    为了执行存储在变量中的命令eval使用命令 gt a echo e a nb wc l gt eval a 2 但如何才能与它结合起来呢 timeout命令 我尝试过以下操作 这给了我错误的输出 gt timeout 10 a a b wc
  • 如何替换“docker run”命令中的变量值

    我正在使用 bash 脚本并尝试分配指纹值 如下所示 export FINGERPRINT D0 19 C5 80 42 66 56 AC 6F docker run rm i v var run docker sock var run d
  • 为什么减法返回 - 符号

    我对简单的减法有疑问 但我不明白出了什么问题 我的代码 start date s N cut b1 13 Treatment end date s N cut b1 13 delta expr end start echo delta de
  • Python3 http.server:将日志保存到文件中

    我使用Python3 6编写了一个简单的HTTP服务器来重定向所有请求 我写的文件可以找到here https github com kmahyyg learn py3 blob master antiscanhttp py 我可以在 Ub
  • 保存和恢复陷阱状态?管理多个陷阱处理程序的简单方法?

    有什么好的方法可以覆盖bash陷阱处理程序不会永久破坏可能已设置或尚未设置的现有处理程序 动态管理任意陷阱例程链怎么样 有没有办法保存陷阱处理程序的当前状态 以便以后可以恢复 在 Bash 中保存和恢复陷阱处理程序状态 我将提交以下堆栈实现
  • 设置 Pyenv 的路径

    我正在尝试在我的服务器中设置 Pyenv 的加载路径 bashrc file 我正在关注这个tutorial https realpython com intro to pyenv 它要求我们在哪里设置pyenv到加载路径 然而 在我的 b
  • POSIX SH 构建循环变量,其元素包含空格

    这是我需要的代码 bin sh x1 a1 a2 x2 b1 b2 list SOMETHING for x in list do echo x done 以及我想要的输出 a1 a2 b1 b2 问题是 应该做什么SOMETHING是 我
  • 在C语言中如何清屏? [复制]

    这个问题在这里已经有答案了 我想清除屏幕上的所有文字 我尝试过使用 include
  • 如何通过 shell 脚本确定网页是否存在?

    我正在尝试制作一个程序 可以将一系列漫画扫描转换为一个 pdf 文件 并且我不想尝试下载图片来确定我是否有正确的网址 是否有一个 shell 脚本命令可以用来检查网页是否存在 在 NIX 下 您可以使用curl发出一个简单的HEAD要求 H
  • 规范化 solaris 上的路径名

    在 GNU 系统上我只会使用readlink f SOME PATH 但 Solaris 没有 readlink 我更喜欢在 bash 中运行良好的程序 但如果需要的话其他程序也可以 Edit 到目前为止 我想到的最好的方法是使用 cd 和
  • 目录 * 和文件顺序

    我需要将目录中的所有文件连接到一个文件 但具有指定名称的文件必须位于输出的顶部 只是在做cat gt result将按字母顺序连接所有文件 有什么办法告诉猫放置文件vars css或任何其他输出的开头 现在我只是重命名文件需要首先000 f
  • 使用 Sphinx 时,如何记录没有文档字符串的成员?

    我正在为我发布的包编写文档 我发现您的文档越全面 人们就越容易找到您的包来使用 废话 实际上 我在充满爱心地编写代码的所有功能和细节方面获得了很多乐趣 然而 我对如何为类级变量编写与 Sphinx 兼容的文档感到完全困惑 特别是 我有一些e
  • 使用 Javascript eval() 100% 安全吗?

    我正在编写一个生成 Javascript 代码的 PHP 库 Javascript 代码有许多名为component001 component002 etc 页面通过 AJAX 动态加载 我需要通过 URL 变量传递组件的名称 然后由脚本进
  • powershell stdin 管道和重定向

    你好 我一直在制作一个小的跨平台脚 本 我可以将其卷曲并通过管道传输到bash和Powershell中 基本思想是服务器向解释器发送一个命令 然后它给出一个命令将所有输出重定向到标准输出 bash 中的一个例子是 some commands

随机推荐