我一次又一次地看到Bash在Stack Overflow上使用eval的答案,并且答案得到了抨击,双关语是为了使用这种"邪恶"结构.为什么eval这么邪恶?
如果eval不能安全使用,我应该使用什么呢?
有没有办法让编译的命令行程序告诉bash或csh它不希望扩展其参数中的任何通配符?
例如,可能需要一个shell命令,如:
foo *
简单地返回该字符的数字ASCII值.
我有一个Bash脚本,我想在传递的参数中保留引号.
例:
./test.sh this is "some test"
然后我想使用这些参数,并重用它们,包括整个参数列表的引号和引号.
我尝试使用\"$@\",但删除了列表中的引号.
我该如何做到这一点?
我想要做的是,作为函数的输入,可以包括引号(单引号或双引号)和与该函数提供的行完全相同的回声.例如:
function doit {
   printf "%s " ${@} 
   eval "${@}"
   printf " # [%3d]\n" ${?}
}
其中,给出以下输入
doit VAR=42
doit echo 'single quote $VAR'
doit echo "double quote $VAR"
产量如下:
VAR=42  # [  0]
echo single quote $VAR  # [  0]
echo double quote 42  # [  0]
所以变量扩展的语义就像我期望的那样得到保留,但是我无法得到提供给函数的行的确切格式.我想要的是doit echo 'single quote $VAR'结果echo 'single quote $VAR'.
我确信这与bash在传递给函数之前处理参数有关; 我只是想找个方法(如果可能的话).
所以我的目的是影响脚本的执行,同时提供执行的精确副本,可以用作诊断工具,包括每个步骤的退出状态.
虽然我可以通过做类似的事情来获得上述所需的行为
while read line ; do 
   doit ${line}
done < ${INPUT}
面对控制结构(即等) …
与此相关:在bash参数中保留引号
一个简单的例子,我只是用nohup... 运行一个命令
#!/bin/bash
nohup "$@"
...
./myscript gedit some\ file\ with\ spaces.txt
这很好用.但是,我不知道在使用中间变量时如何保持参数的正确位被转义...
#!/bin/bash
CMD="$@"
printf "%q\n" "$CMD" #for debugging
nohup $CMD
我已经尝试了一些排列,并且在所有情况下都没有任何作用.我错过了什么?理想情况下,我希望能够在$CMD之前进行修改nohup.
我需要能够备份并稍后使用(读取和打印以及作为参数传递给另一个命令)所有输入参数到 bash 程序,但无法弄清楚。这是我的尝试:
back_up_all_input_args.sh:
#!/usr/bin/env bash
all_args1="$@"
all_args2="$(printf "%q " "$@")"
# Simulate parsing the input args here
# - see: https://stackoverflow.com/a/14203146/4561887
shift # remove 1st arg
shift # remove 2nd arg
echo "$@"
echo "$all_args1"
echo "$all_args2"
# Do another program call with all input args here
# rg "$all_args1"  # FAILS
# rg "$all_args2"  # FAILS
示例运行和输出:
Run Code Online (Sandbox Code Playgroud)$ ./backup_all_input_args.sh arg1 "arg 2" "arg 3" arg 3 arg1 arg 2 arg 3 arg1 arg\ 2 arg\ 3
我的第一个方法是用 来支持论点 …