脚本读取输出以运行下一个命令

时间:2021-10-03 22:11:31

I am unable to do this, as I am new to scripting, I need a script which should give run on all server mentioned in a file.

我无法做到这一点,因为我不熟悉脚本,我需要一个脚本,它应该在文件中提到的所有服务器上运行。

First it should login to the server
1st command is netstat -tulpun | grep -i port (port & server list are in the same file)

首先它应该登录到服务器第一个命令是netstat -tulpun | grep -i port(端口和服务器列表在同一个文件中)

I may get 3 to 4 output here but I need only 25 port output not the others

我可能在这里获得3到4个输出,但我只需要25个端口输出而不是其他输出

# netstat -tulpun | grep -i 25   
tcp        0      0 127.0.0.1:25                0.0.0.0:*             LISTEN    25/sendmail  
udp        0      0 0.0.0.0:19258               0.0.0.0:*  

2nd command is ps -ef | grep the PID which I get from the netstat command

第二个命令是ps -ef | grep我从netstat命令得到的PID

the output should look as mentioned below

输出应如下所述

=====  
Server1  
Port 1311  
root      8063  8062  0  2014 ?        00:08:06 /opt/dm_cd -run  

=====  
Server2  
Port 1311  
root      6844  6843  0  2014 ?        00:20:22 /etc/bin/linux/ds -run  

=====  
Server3  
Port 8000  
applmgr   1505  4215  0  2014 ?        00:05:44 /app/Apache/bin/httpd -d   

=====   
Server4  
Port 1311  
root      8122  8121  0  2014 ?        01:30:36 /opt/dsvcd -run  

=====  
Server5  
Port 1888  
root     10097 10096  0  2014 ?        01:29:00 /etc/32d -run  

while read -r -u10 server port line
do
echo ========== server: "$server" port: "$port" ==========
ssh -qn "$server" "netstat -tulpun | grep -E \"\b$port\b\"" | awk '{print $7}' | grep "/" | awk -F "/" '{print $1}'
echo
done 10< demo

读取-r -u10服务器端口行做回显==========服务器:“$ server”端口:“$ port”========== ssh -qn“$ server” “netstat -tulpun | grep -E \”\ b $ port \ b \“”| awk'{print $ 7}'| grep“/”| awk -F“/”'{print $ 1}'echo done 10

netstat -tulpunt | grep -E ":25 " | awk '{print $7}' | grep "/" | awk -F "/" '{print $1}' | xargs -I % bash -c 'echo Port % && ps -ef | grep % && echo ' | grep -v grep

netstat -tulpunt | grep -E“:25”| awk'{print $ 7}'| grep“/”| awk -F“/”'{print $ 1}'| xargs -I%bash -c'echo Port%&& ps -ef | grep%&& echo'| grep -v grep

2 个解决方案

#1


0  

I have no service running on port 25, but I have service on port 5433, so I will use in this port for demo.

我没有在端口25上运行服务,但我在端口5433上有服务,所以我将在这个端口用于演示。

My environment

$ ps -ef | grep ':5433'
daniel@synapse:~$ ps -ef | grep 5433
daniel    2824  1967  1 12:36 ?        00:05:43 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
daniel    9455  2702  0 20:27 pts/1    00:00:00 grep --color=auto 5433

We should avoid usage in grep, otherwise you will get garbage-lines with grep in output.

我们应该避免在grep中使用,否则你将在输出中获得带有grep的垃圾行。

So how we can get a desired output?

那么我们如何才能获得理想的输出?

  • with lsof extract a process id (application PID)
  • 用lsof提取进程id(应用程序PID)

  • with ps get desired output
  • 用ps获得所需的输出

Demo:

$ ps -p $(lsof -ti tcp:5433) o user=,pid=,ppid=,c=,stime=,tty=,time=,command=
daniel    2824  1967  1 12:36 ?        00:05:53 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4

As we can see output is identical to ps -ef | grep ${PID} and no garbage lines with grep.

我们可以看到输出与ps -ef |相同grep $ {PID}并且没有带grep的垃圾行。

And now we are ready to write a final script:

现在我们准备写一个最终的脚本:

#!/usr/bin/env bash
# author: Daniel Leybovich

# list of hosts to check
declare -a CLUSTER=(localhost synapse 127.0.0.1 46.210.138.27)

# port
LOOKUP_PORT=5433

# run main task
for HOST in ${CLUSTER[@]}
do
    echo "===="
    echo "HOST: ${HOST}"
    echo "PORT: ${LOOKUP_PORT}"
    ssh -x ${HOST} "ps -p $(lsof -ti tcp:5433) o user=,pid=,ppid=,c=,stime=,tty=,time=,command="    
done

# we are done
exit 0

And here is an output of script:

这是脚本的输出:

daniel@synapse:/tmp$ ./reds.sh
====
HOST: localhost
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: synapse
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: 127.0.0.1
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: 46.210.138.27
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4

Modify script to your need.

根据需要修改脚本。

EDIT

I modified a script.

我修改了一个脚本。

File hosts.txt:

daniel@node1:5433
johns@node1:4803
johns@node2:5444
johns@node3:4803
daniel@node4:80

Script reds.sh:

#!/usr/bin/env bash
# author: Daniel Leybovich

# file with lookup params
HOSTS_FILE=${1}


# run main task
for LINE in $(cat ${HOSTS_FILE})
do
    USER=$(echo ${LINE} | cut -d'@' -f1)
    HOST=$(echo ${LINE} | cut -d'@' -f2 | cut -d':' -f1)
    PORT=$(echo ${LINE} | cut -d':' -f2)
    echo "===="
    echo "HOST: ${HOST}"
    echo "USER: ${USER}"
    echo "PORT: ${PORT}"
    ssh "${USER}@${HOST}" -x \
        "ps -p $(lsof -ti tcp:${PORT}) o user=,pid=,ppid=,c=,stime=,tty=,time=,command="
done

# we are done
exit 0

Output

daniel@synapse:/tmp$ ./reds.sh /tmp/hosts.txt
====
HOST: node1
USER: daniel
PORT: 5433
daniel    2934  1902  1 13:51 ?        00:00:31 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: node1
USER: johns
PORT: 4803
daniel    2932  1902  0 13:51 ?        00:00:00 /opt/vertica/spread/sbin/spread -c /vertica/dev/v_dev_node0001_catalog/spread.conf
====
HOST: node2
USER: johns
PORT: 5444
daniel    1353  1345  0 13:48 ?        00:00:18 /opt/vertica/oss/python/bin/python ./simply_fast.py
====
HOST: node3
USER: johns
PORT: 4803
daniel    2932  1902  0 13:51 ?        00:00:00 /opt/vertica/spread/sbin/spread -c /vertica/dev/v_dev_node0001_catalog/spread.conf
====
HOST: node4
USER: daniel
PORT: 80
daniel    2484  1902  5 13:48 ?        00:02:18 /usr/lib/firefox/firefox

Regards

#2


0  

Begin with

netstat -tulpun

Pipe into grep, but also include the colon and a space to exclude the ports with 25 in it:

管道进入grep,但也包括冒号和空格以排除25中​​的端口:

grep ":25 "

grep“:25”

Then pipe that into AWK to display the seventh column

然后将其导入AWK以显示第七列

awk '{print $7}'

awk'{print $ 7}'

Take only the ones with a slash in it (not the only dashes)

只拿带斜线的(不是唯一的破折号)

grep "/"

Then take the PID

然后拿PID

awk -F "/" '{print $1}'

awk -F“/”'{print $ 1}'

Piping all that gives all process IDs

管道所有提供所有进程ID的管道

netstat -tulpunt | grep ":25 " | awk '{print $7}' | grep "/" | awk -F "/" '{print $1}'

netstat -tulpunt | grep“:25”| awk'{print $ 7}'| grep“/”| awk -F“/”'{print $ 1}'

Now pipe that into xargs to execute a command with that as arguments

现在将其传递到xargs中以执行命令作为参数

netstat -tulpunt | grep ":25 " | awk '{print $7}' | grep "/" | awk -F "/" '{print $1}' | xargs -I % sh -c 'echo Port % && ps -ef | grep % && echo '

netstat -tulpunt | grep“:25”| awk'{print $ 7}'| grep“/”| awk -F“/”'{print $ 1}'| xargs -I%sh -c'echo Port%&& ps -ef | grep%&& echo'

Something like that? Try to understand each step to see what is happening.

那样的东西?尝试了解每个步骤,看看发生了什么。

Edit: to loop through a list of servers, create a bash file like this:

编辑:循环遍历服务器列表,创建一个像这样的bash文件:

#!/bin/bash
cat serverlist.txt | while read line
do
   ssh $line "netstat -tulpunt | grep ':25 ' | awk '{print $7}' | grep '/' | awk -F '/' '{print $1}' | xargs -I % sh -c 'echo Port % && ps -ef | grep % && echo "
done

Save to something.sh and execute with

保存到something.sh并执行

./something.sh

It loops through a list of servers in a file like this

它循环遍历这样的文件中的服务器列表

user1@server1.com
user2@server2.com
...

If you need to give a password, you can do this:

如果您需要提供密码,可以执行以下操作:

user1:pass1@server1.com
user2:pass2@server2.com
...

I did not test this though, so there might be a syntax error somewhere :)

我没有测试过这个,所以可能会出现语法错误:)

#1


0  

I have no service running on port 25, but I have service on port 5433, so I will use in this port for demo.

我没有在端口25上运行服务,但我在端口5433上有服务,所以我将在这个端口用于演示。

My environment

$ ps -ef | grep ':5433'
daniel@synapse:~$ ps -ef | grep 5433
daniel    2824  1967  1 12:36 ?        00:05:43 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
daniel    9455  2702  0 20:27 pts/1    00:00:00 grep --color=auto 5433

We should avoid usage in grep, otherwise you will get garbage-lines with grep in output.

我们应该避免在grep中使用,否则你将在输出中获得带有grep的垃圾行。

So how we can get a desired output?

那么我们如何才能获得理想的输出?

  • with lsof extract a process id (application PID)
  • 用lsof提取进程id(应用程序PID)

  • with ps get desired output
  • 用ps获得所需的输出

Demo:

$ ps -p $(lsof -ti tcp:5433) o user=,pid=,ppid=,c=,stime=,tty=,time=,command=
daniel    2824  1967  1 12:36 ?        00:05:53 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4

As we can see output is identical to ps -ef | grep ${PID} and no garbage lines with grep.

我们可以看到输出与ps -ef |相同grep $ {PID}并且没有带grep的垃圾行。

And now we are ready to write a final script:

现在我们准备写一个最终的脚本:

#!/usr/bin/env bash
# author: Daniel Leybovich

# list of hosts to check
declare -a CLUSTER=(localhost synapse 127.0.0.1 46.210.138.27)

# port
LOOKUP_PORT=5433

# run main task
for HOST in ${CLUSTER[@]}
do
    echo "===="
    echo "HOST: ${HOST}"
    echo "PORT: ${LOOKUP_PORT}"
    ssh -x ${HOST} "ps -p $(lsof -ti tcp:5433) o user=,pid=,ppid=,c=,stime=,tty=,time=,command="    
done

# we are done
exit 0

And here is an output of script:

这是脚本的输出:

daniel@synapse:/tmp$ ./reds.sh
====
HOST: localhost
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: synapse
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: 127.0.0.1
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: 46.210.138.27
PORT: 5433
daniel    2824  1967  1 12:36 ?        00:06:01 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4

Modify script to your need.

根据需要修改脚本。

EDIT

I modified a script.

我修改了一个脚本。

File hosts.txt:

daniel@node1:5433
johns@node1:4803
johns@node2:5444
johns@node3:4803
daniel@node4:80

Script reds.sh:

#!/usr/bin/env bash
# author: Daniel Leybovich

# file with lookup params
HOSTS_FILE=${1}


# run main task
for LINE in $(cat ${HOSTS_FILE})
do
    USER=$(echo ${LINE} | cut -d'@' -f1)
    HOST=$(echo ${LINE} | cut -d'@' -f2 | cut -d':' -f1)
    PORT=$(echo ${LINE} | cut -d':' -f2)
    echo "===="
    echo "HOST: ${HOST}"
    echo "USER: ${USER}"
    echo "PORT: ${PORT}"
    ssh "${USER}@${HOST}" -x \
        "ps -p $(lsof -ti tcp:${PORT}) o user=,pid=,ppid=,c=,stime=,tty=,time=,command="
done

# we are done
exit 0

Output

daniel@synapse:/tmp$ ./reds.sh /tmp/hosts.txt
====
HOST: node1
USER: daniel
PORT: 5433
daniel    2934  1902  1 13:51 ?        00:00:31 /opt/vertica/bin/vertica -D /vertica/dev/v_dev_node0001_catalog -C dev -n v_dev_node0001 -h 127.0.0.1 -p 5433 -P 4803 -Y ipv4
====
HOST: node1
USER: johns
PORT: 4803
daniel    2932  1902  0 13:51 ?        00:00:00 /opt/vertica/spread/sbin/spread -c /vertica/dev/v_dev_node0001_catalog/spread.conf
====
HOST: node2
USER: johns
PORT: 5444
daniel    1353  1345  0 13:48 ?        00:00:18 /opt/vertica/oss/python/bin/python ./simply_fast.py
====
HOST: node3
USER: johns
PORT: 4803
daniel    2932  1902  0 13:51 ?        00:00:00 /opt/vertica/spread/sbin/spread -c /vertica/dev/v_dev_node0001_catalog/spread.conf
====
HOST: node4
USER: daniel
PORT: 80
daniel    2484  1902  5 13:48 ?        00:02:18 /usr/lib/firefox/firefox

Regards

#2


0  

Begin with

netstat -tulpun

Pipe into grep, but also include the colon and a space to exclude the ports with 25 in it:

管道进入grep,但也包括冒号和空格以排除25中​​的端口:

grep ":25 "

grep“:25”

Then pipe that into AWK to display the seventh column

然后将其导入AWK以显示第七列

awk '{print $7}'

awk'{print $ 7}'

Take only the ones with a slash in it (not the only dashes)

只拿带斜线的(不是唯一的破折号)

grep "/"

Then take the PID

然后拿PID

awk -F "/" '{print $1}'

awk -F“/”'{print $ 1}'

Piping all that gives all process IDs

管道所有提供所有进程ID的管道

netstat -tulpunt | grep ":25 " | awk '{print $7}' | grep "/" | awk -F "/" '{print $1}'

netstat -tulpunt | grep“:25”| awk'{print $ 7}'| grep“/”| awk -F“/”'{print $ 1}'

Now pipe that into xargs to execute a command with that as arguments

现在将其传递到xargs中以执行命令作为参数

netstat -tulpunt | grep ":25 " | awk '{print $7}' | grep "/" | awk -F "/" '{print $1}' | xargs -I % sh -c 'echo Port % && ps -ef | grep % && echo '

netstat -tulpunt | grep“:25”| awk'{print $ 7}'| grep“/”| awk -F“/”'{print $ 1}'| xargs -I%sh -c'echo Port%&& ps -ef | grep%&& echo'

Something like that? Try to understand each step to see what is happening.

那样的东西?尝试了解每个步骤,看看发生了什么。

Edit: to loop through a list of servers, create a bash file like this:

编辑:循环遍历服务器列表,创建一个像这样的bash文件:

#!/bin/bash
cat serverlist.txt | while read line
do
   ssh $line "netstat -tulpunt | grep ':25 ' | awk '{print $7}' | grep '/' | awk -F '/' '{print $1}' | xargs -I % sh -c 'echo Port % && ps -ef | grep % && echo "
done

Save to something.sh and execute with

保存到something.sh并执行

./something.sh

It loops through a list of servers in a file like this

它循环遍历这样的文件中的服务器列表

user1@server1.com
user2@server2.com
...

If you need to give a password, you can do this:

如果您需要提供密码,可以执行以下操作:

user1:pass1@server1.com
user2:pass2@server2.com
...

I did not test this though, so there might be a syntax error somewhere :)

我没有测试过这个,所以可能会出现语法错误:)