bash - 仅在设置值时扩展为标志
问题描述
我有一些逻辑,例如:
if [[ -n "$SSH_CLIENT" ]]
then
sflag="-s $(echo "$SSH_CLIENT" | awk '{ print $1}')"
else
sflag=''
fi
iptables -A MY_RULE "$sflag" -p tcp -m tcp --dport 9999 -m conntrack -j ACCEPT
换句话说,我想模仿只将-s
标志传递给iptables
ifSSH_CLIENT
设置。实际发生的是无意中传递了空字符串。
我感兴趣的是,为了不重复两个相当长的iptables
调用,是否有可能扩展标志name 和 value。例如,上面的命令应该扩展为
iptables -A MY_RULE -s 10.10.10.10 -p tcp -m tcp ...
, 或者iptables -A MY_RULE -p tcp -m tcp ...
问题是在第二种情况下,展开实际上变成了:
iptables -A MY_RULE '' -p tcp -m tcp
并且有一个额外的空字符串被视为位置参数。我怎样才能正确地做到这一点?
解决方案
所有 POSIX shell:使用${var+ ...expansion...}
仅当设置了变量时, Using${var+ ...words...}
才允许您拥有任意数量的单词:
iptables -A MY_RULE \
${SSH_CLIENT+ -s "${SSH_CLIENT%% *}"} \
-p tcp -m tcp --dport 9999 -m conntrack -j ACCEPT
在这里,如果设置了 if-and-only-if SSH_CLIENT
,我们添加-s
后面的所有内容,SSH_CLIENT
直到第一个空格。
Bash(和其他扩展外壳):使用数组
更通用的方法是在要将多个字符串表示为单个值时使用数组:
ssh_client_args=( )
[[ $SSH_CLIENT ]] && ssh_client_args+=( -s "${SSH_CLIENT%% *}" )
iptables -A MY_RULE "${ssh_client_args[@]}" -p tcp -m tcp --dport 9999 -m conntrack -j ACCEPT
语法"${var%% *}
是一个参数扩展,它扩展为var
以空格开头的最长可能后缀;因此,留下第一个词。这比运行外部程序(如awk
. 另请参阅描述本机 bash 字符串操作的一般最佳实践的BashFAQ #100 。
推荐阅读
- sql - 使用条件将字段从一列复制到另一列
- ios - 在 navigationBarTitle 中添加视图 - SwiftUI
- javascript - 如何使用在单独脚本中定义的 Razor 中的对象
- download - 如何在电子中启用 chrome:webrtc-internals 以下载 webrtc getstats 文件
- python-3.x - 操作列表索引值,这个python代码有什么问题?
- c# - 仅具有类名并在页面上重复多次的元素。硒 c#
- sql-server - 将 vardhar 值“abc”转换为数据类型 int 时转换失败
- excel - Word 在 Excel 的 VBA 控制下不断出错
- amazon-web-services - App Sync 在“items”键下推送 dynamodb 中的对象
- java - 如何释放 apache camel 中的内存使用量?