我正在尝试使用shell脚本禁用apache负载均衡器中的节点。我在网上得到了一些想法,但我无法理解为禁用负载平衡器中的节点而编写的代码。以下是我所指的代码:
disable() {
balancer=$1
worker=$2
if [ -z "$balancer" ] || [ -z "$worker" ]; then
echo "Usage: $0 [-s host] [-p port] [-m balancer-manager] disable balancer_name worker_route"
echo " balancer_name : balancer/cluster name"
echo " worker_route : worker route e.g.)"
exit 1
fi
echo "Disabling $2 of $1..."
nonce=`$CURL -s "http://${server}:${port}/${manager}" | grep nonce | grep "${balancer}" | sed "s/.*nonce=(.*)['"].*/1/" | tail -n 1`
if [ -z "$nonce" ]; then
echo "balancer_name ($balancer) not found"
exit 1
fi
你能帮我理解上面提到的代码的含义吗。特别是关于nonce。
拆开您的命令,您可能首先需要了解管道在Unix中是如何工作的。每个命令都有标准输入和标准输出;符号CCD_ 1是从CCD_ 2输出的标准成为CCD_ 3的标准输入的流水线;因此,我们传递first
将打印的任何内容作为second
的输入,而不是first
打印任何内容,或者second
从文件中读取某些内容。
nonce=...
将...
分配给变量first | second
0。该名称表明,它旨在用作加密随机数`cmd`
是$(cmd)
的过时同义词。该命令替换用其输出替换(替换(命令cmd
。所以nonce
的值将是这个子shell打印到标准输出的任何值$CURL
可能会运行curl
,但我们只能猜测。通常,您会确保curl
在PATH
上,并简单地使用文字命令curl
first
0获取URL的内容并将其打印到标准输出。-s
选项禁止显示任何状态消息。输出通过管道传输到grep nonce
,它将包含正则表达式nonce
的匹配的任何行打印到标准输出(它只是在一行的任何地方逐字匹配该文本(,并抑制所有其他行;然后通过管道输送到- CCD_ 24,其类似地仅打印与变量
balancer
所包含的任何正则表达式相匹配的行(大括号是无害的但无用的(;然后通过管道输送到 sed "s/.*nonce=(.*)['"].*/1/"
,它挑选括号之间的东西——直到nonce=
之后的最后一个单引号或双引号的任何东西;然后通过管道输送到- CCD_ 28,丢弃除最后一行之外的所有行
总之,从远程URL后面的内容中挑选出最后一个nonce=
,并打印出来,但只能打印到第一个单引号或双引号之前。
这一切都相当笨拙和低效;任何涉及多个second
0和sed
命令的管道都可能被重构为一个简单的Awk脚本。
nonce=$(curl -s "http://${server}:${port}/${manager}" |
awk -v b="$balancer" '/nonce/ && $0 ~ b {
sub(/^.*nonce=/, ""); sub(/[ 47 42][^ 47 42]*$/, ""); n=$0 }
END { print n }')
尤其是sed
命令看起来有点模糊;通常,我们希望提取的输出是引号之间的,但这会提取到最后一个单引号或双引号之前。命令sed -n 's/.*(stuff).*/1/p'
将是仅打印我们实际提取stuff
的行的正常方式。但在看不到URL包含什么的情况下,我们只能猜测这是否正确。当然,传统语法会允许作者完全省略第一个grep
。
获得最后一个nonce
可能只是一个护栏,以确保永远不会超过一个;我想我们通常只期待一场比赛。
grep
、sed
和Awk都对正则表达式进行运算。如果您是regex的新手,可以访问Stack Overflowregex
标签信息页面,并查看末尾的学习资源列表。
展望未来,可能会尝试https://explainshell.com/在请求人类援助之前。