如何在 (ba)sh 命令中获取/解析重定向"target"



我必须通过模拟器运行一个二进制文件,但是这个二进制文件是一个庞大而复杂的基准测试套件的一部分。那么在正常的系统中应该是这样的:

# First form
./binary -long=list -of=args <input.txt >std.out 2>std.err

需要看起来像这样:

# second form
simulator -c ./binary -o "-long=list -of=args" -i input.txt --output=std.out --errout=std.err 

基准测试套装正在传递命令,即在(bash)变量(例如$CMD="./binary -long=list -of=args <input.txt >std.out 2>std.err")中包含所有内容(args和重定向)的二进制文件,我需要找出所有重定向的目标(即示例中的intpu.txt,std.outstd.err),因此我可以将第一种形式的命令转换为第二种形式的命令)。

那么,是否有一种方法,例如,告诉bash接受命令$CMD,其中包含二进制文件,参数和重定向,并解析它,然后返回,说,什么是输入重定向(即input.txt),或其他重定向之一(std.outstd.err)?

无需手动解析当然…

像这样:

$ CMD="./binary -long=list -of=args <input.txt >std.out 2>std.err"
$ bash -secret_option_to_parse_redirect_target=input "$CMD"
intpu.txt
$ bash -secret_option_to_parse_redirect_target=output "$CMD"
std.out
$ bash -secret_option_to_parse_redirect_target=error "$CMD"
std.err

如果您信任cmd能够解析为单个简单命令,则可以使用eval在其周围添加一个包装器,以读取命令行和活动重定向。查看运行在https://replit.com/@CharlesDuffy2/grouchyhelpessinformationtechnology# main.sh

的代码请注意,这需要操作系统具有与Linux提供的/proc/*/fd接口兼容的操作系统。

read_fd() {
local fd_num dest_var fd_dest default_val bash_pid=$BASHPID
fd_num=$1; dest_var=$2; default_val=${3:-"/proc/self/fd/$fd_num"}
printf -v "$dest_var" %s "$default_val"
[[ -e /proc/$bash_pid/fd/$fd_nume ]] || return
fd_dest="$(readlink "/proc/$bash_pid/fd/$fd_num")" || return
[[ -e $fd_dest ]] || return
printf -v "$dest_var" %s "$fd_dest"
}
parse_cmd() {
read_fd 0 stdin_src
read_fd 1 stdout_dest
read_fd 2 stderr_dest
argv_dest=( "$@" )
}

…用作:

# all-caps variable names are reserved; do not use them in your own code
cmd="./binary -long=list -of=args <input.txt >std.out 2>std.err"
# inputs need to exist for redirections to work
touch input.txt
eval "parse_cmd $cmd"
echo "stdout destination is $stdout_dest"
echo "stderr destination is $stderr_dest"
echo "stdin source is $stdin_src"
echo "argument list follows, one per line:"
printf ' - %qn' "${argv_dest[@]}"
echo
echo "to run this, you could use:"
echo "${argv_dest[*]@Q} <$stdin_src >$stdout_dest 2>$stderr_dest"