bash - 将带有参数的 bash 命令传递给函数
问题描述
我有一个非常大的 shell 脚本,它围绕特定应用程序的许多日常管理任务提供标准化的流程和逻辑包装器。
为了简化调试和维护,我尝试创建一个 RUN 函数,它可以根据标志在屏幕或日志文件输出之间切换:
##
# Executes the command, which is passed as $1
# If debug mode is enabled, dump full execution output to screen
##
function RUN()
{
if $debug; then
# output to screen
$*
else
# Suppress screen output, but capture all output in logs
$* &>> $logs
fi
}
有了这样的想法,通过使用调试标志调用我的脚本,我可以获得完整的输出到屏幕:
./script -d PARAMETERS
不幸的是,我在脚本中使用这个 RUN 函数取得了非常不同的成功。我的一些功能可以正常工作,而另一些则不能。在我添加 RUN 函数包装器之前,该脚本运行良好,但我真的需要它提供的附加功能(当它工作时)。
以下是我的脚本中 RUN 函数的一些用例示例:
# Example 1, set vars for a loop
local PARAM_LIST=$(RUN "BINARY PARAM1 PARAM2 -PARAM3")
for p in ${PARAM_LIST[@]}; do
# Stuff
done
# Example 2, basic execution with pipes
$(RUN "BINARY PARAM1 PARAM2 -PARAM3 | awk {'{ print $2,$1 }'} | xargs -n1 BINARY PARAM1 PARAM4")
# Example 3, conditional execution
for i in ${!ARRAY[@]}; do
if [[ ! $(RUN "BINARY PARAM1 PARAM2 $i") ]]; then
# do stuff
fi
done
我相当确定 bash 语法是我出错的地方,但在追踪根本原因时遇到了麻烦。
谁能帮忙指出我做错了什么?
解决方案
它失败是因为您的函数需要多个命令参数(如sudo
, env
, xargs
, find
, 等),但您改为使用 shell 命令将单个字符串传递给它(如 for su
, ssh
, sh -c
)。
您的函数需要一个 shell 命令:
function RUN()
{
if $debug; then
echo "Executing: $1" >&2
# output to screen
eval "$1"
else
# Suppress screen output, but capture all output in logs
eval "$1" &>> $logs
fi
}
您必须正确转义所有命令:
# Fails because $2 and $1 are not being escaped:
RUN "env | awk -F= '{ print $2, $1 }'"
# Succeeds because command is correctly escaped:
RUN "env | awk -F= '{ print \$2, \$1 }'"
另一个需要考虑的选项是在调试模式下编写整个脚本,然后可以选择压缩输出,这样您就不必添加任何额外的转义:
# Save stdout&stderr in case we need it
exec 5>&1 6>&2
# Optionally squash output
if ! "${debug:false}"
then
exec &>> "$logs"
fi
# This only shows output if debug is on
BINARY PARAM1 PARAM2 -PARAM3 | awk '{ print $2,$1 }' | xargs -n1 BINARY PARAM1 PARAM4
# This always writes to stderr, whether debug is enabled or not
echo "Done" >&6
推荐阅读
- mysql - MySQL 连接到 Google Cloud SQL 实例语法错误
- haskell - Haskell 如何编译大数?
- multithreading - Spring Boot:我们如何实现多个@Scheduled 任务,每个任务都有自己的线程池?
- buffalo - show can set disabled pop 错误:mysql select one: sql: no rows in result set
- react-native - 如何在 react-native 中根据 useSelector 挂钩的值操作视图
- concurrency - 判断高并发的原因
- powerquery - 在 PowerQuery 中使用发布
- javascript - RangeError:超过最大调用堆栈大小 Javascript 问题
- java - 满足条件的元素的Java迭代器
- php - apache在发布请求时返回403错误,输入变量计数保持不变,值发生变化