打印包含空格和特殊字符的最后一列

打印包含空格和特殊字符的最后一列

我需要一个完整的路径/命令来启动一个暴露在网络上的进程 - 监听 tcp/udp 。我确实设法使用下面的“一行代码”获得了所有这些:

netstat -nlp46|tail -n +3 |   while IFS=" " read -r -a line; 
do nb=${#line[@]}; 
PID=$(echo ${line[$((nb - 1))]} | awk -F'/' '{print $1}'); 
CMD=$(ps -ef|awk '$2 == '"$PID" |awk -F" " '{out=$8; for(i=9;i<=NF;i++){out=out""$i}; print out}');
echo $PID^$CMD; 
done

但是当进程在命令行中包含一些特殊字符时,例如瘦服务器,脚本会出现以下错误

awk: line 1: missing ) near end of line

当我针对该进程运行部分脚本时,没有遇到任何问题

root@ftp-host02:~# PID=15000; COMMAND=$(ps -ef|awk '$2 == '"$PID" |awk '{out=$8; for(i=9;i<=NF;i++){out=out" "$i}; print out}'); 
echo $COMMAND

thin server (0.0.0.0:3000)

我在这里做错了什么?

谢谢

答案1

错误在这里:awk '$2 == '"$PID"

  • 如果$PID不是严格的数字,那么您正在对未加引号的字符串进行相等性检查,因此实际上,谁知道 awk 将如何解释它?

    $ PID="3000)"
    $ echo hello | mawk '$2 == '"$PID"
    mawk: line 1: extra ')'
    

将 shell 变量作为 awk 变量传递给 awk(带有选项-v)可以解决该问题。

通过其他方式清理代码,我们有:

netstat -nlp46 | 
tail -n +3 | 
while IFS=" " read -r -a fields; do 
    nb=${#fields[@]}
    PID=${fields[nb-1]%%/*}
    CMD=$( ps -ef | awk -v pid="$PID" '$2 == pid {out=$8; for(i=9;i<=NF;i++){out=out $i}; print out}' );
    echo "$PID^$CMD"; 
done

笔记:

  • 适当的缩进对于代码的可读性有很大帮助
  • 数字索引数组的索引已在算术上下文中求值,因此${ary[n-1]}可以工作
  • 您可以使用 shell 参数扩展删除斜杠及其后续字符,因此不需要 awk 来获取 PID
  • 你不需要将 awk 连接到 awk:consolidate
  • -v使用选项将 shell 变量传递到 awk

答案2

你可以尝试一下:

for i in $(netstat -atnp | awk '{ print $7 }' | grep ^[0-9] | awk -F\/ '{ print $1 }'); do echo "PID: $i " $(ps faxuwwww | grep $i); done

相关内容