สคริปต์เพื่อ ssh และเรียกใช้คำสั่งไม่ทำงาน


10

ด้านล่างเป็นสคริปต์

ฉันต้องการลงชื่อเข้าใช้เซิร์ฟเวอร์หลายเครื่องและตรวจสอบรุ่นเคอร์เนล

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done

ฉันคาดว่าผลผลิตที่จะไป ..

server1_hostname
kernel_version
server2_hostname
kernel_version

และอื่น ๆ ..

ฉันใช้สคริปต์นี้กับเซิร์ฟเวอร์ประมาณ 80 แห่งใน server.txt

และผลลัพธ์ที่ฉันได้รับก็เหมือน .....

Pseudo-terminal will not be allocated because stdin is not a terminal. 
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.

========================================================================
================================ WARNING ===============================
========================================================================
This system is solely for the use of authorized personnel. Individuals
using this system are subject to having some or all of their activities
monitored and recorded. Anyone using this system expressly consents to
such monitoring and is advised that any unauthorized or improper use of
this system may result in disciplinary action up to and including
termination of employment. Violators may also be subject to civil and/or
criminal penalties.
========================================================================

Warning: no access to tty (Bad file descriptor).
Thus no job control in this shell.
xxxxdev01
2.6.32-431.23.3.el6.x86_64
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.

ที่นี่ฉันได้รับผลลัพธ์เพียง 1 โฮสต์ซึ่งก็คือxxxxdev01และที่มาพร้อมกับแบนเนอร์ ssh และคำเตือนอื่น ๆ

ฉันต้องการเอาต์พุตของโฮสต์อื่น ๆ ทั้งหมดและไม่มีแบนเนอร์ ssh .. เกิดอะไรขึ้นที่นี่


จะเกิดอะไรขึ้นถ้าคุณใช้เซิร์ฟเวอร์ตัวใดตัวหนึ่งแล้วทำการรันsshpass -p password root@server histname?
terdon

1
ใช้ssh -t -t root@... เพื่อบังคับใช้เทอร์มินัลหลอก
garethTheRed

คำตอบ:


11

ฉันไม่สามารถบอกคุณได้ว่าทำไมคุณไม่ได้รับผลลัพธ์ที่คาดหวังจากhostnameและunameคำสั่ง แต่ฉันสามารถช่วยกับข้อความภายนอก

บรรทัด "Pseudo-terminal" กำลังถูกพิมพ์โดยsshเนื่องจากพยายามจัดสรร TTY เป็นค่าเริ่มต้นเมื่อไม่มีคำสั่งที่ต้องดำเนินการให้ในบรรทัดคำสั่ง คุณสามารถหลีกเลี่ยงข้อความนั้นได้โดยเพิ่ม "-T" ลงในคำสั่ง ssh:

sshpass -p password ssh -T root@$line

บรรทัด "คำเตือน: ไม่มีการเข้าถึง tty" มาจากเชลล์บนระบบรีโมต cshและtcshจะพิมพ์ข้อความนั้นในบางกรณี อาจเป็นไปได้ว่ามีบางสิ่งใน.cshrcไฟล์หรือคล้ายกันในระบบรีโมตพยายามเข้าถึงคุณลักษณะบางอย่างที่ต้องใช้ TTY


4

ใช้รหัสต่อไปนี้

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
  sshpass -p password ssh root@$line 'hostname;uname -r'
done

นี่คือสิ่งที่ฉันพยายามก่อน แต่มันก็ไม่ได้ให้ผลลัพธ์ที่คาดหวัง
Gokul

1

หากโฮสต์ของคุณถูกเก็บไว้ดังต่อไปนี้ server.txt

host1.tld
host2.tld
....

คุณสามารถ

mapfile -t myhosts < server.txt; for host in "${myhosts[@]}"; do ssh username@"$host" 'hostname;uname -r'; done

1

stdin ไม่สามารถเข้าถึงคำสั่งระยะไกลของคุณ สิ่งที่คุณสามารถทำได้คือใช้แฟล็ก "-s" ของ bash เพื่ออ่านคำสั่งจาก stdin:

จากทุบตีคู่มือ:

-s        If the -s option is present, or if no arguments remain after
          option processing, then commands are read from the standard 
          input.  This option allows the positional parameters to be set
          when  invoking  an  interactive shell.

ดังนั้นควรทำสิ่งที่คุณต้องการ:

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
    sshpass -p password ssh root@$line bash -s << EOF
hostname
uname -r
EOF
done

ดูเพิ่มเติมที่: /programming/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine


1

มันใช้งานได้ดีสำหรับฉัน:

 # cat hostsname.txt 
operation01  172.20.68.37 5fDviDEwew
ngx-gw01     172.20.68.36 FiPp2UpRyu
gateway01    172.20.68.35 KeMbe57zzb
vehicle01    172.20.68.34 FElJ3ArM0m

# cat hostsname.txt | while read hostname ipaddr passwd; do sshpass -p $passwd /usr/bin/ssh-copy-id $ipaddr;done

โปรดทราบว่าใช้-t -tแทน-Tเพื่อหลีกเลี่ยงข้อผิดพลาด

Pseudo-terminal จะไม่ถูกจัดสรรเนื่องจาก stdin ไม่ใช่เทอร์มินัล


1
คุณควรอ่านข้อมูลเกี่ยวกับการจัดรูปแบบ คำตอบของคุณอาจยอดเยี่ยม แต่ตอนนี้มันอ่านไม่ออก
roaima

0

ฉันเดา ssh ในขณะที่กินส่วนที่เหลือเพื่อ stdin คุณอาจจะหมายทุบตีคำถามที่พบบ่อย 89สำหรับรายละเอียด ด้วย FileDescriptor รหัสต่อไปนี้ควรทำงานตามที่คุณคาดหวัง

while read line <& 7
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done 7< server.txt

วิธีทางเลือกคือใช้ / dev / null สำหรับ ssh FileDescriptor สามารถถูกละเว้น `ขณะอ่านบรรทัด ทำ sshpass -p รหัสผ่าน ssh root @ $ line </ dev / null << EOF .... ทำ <server.txt`
Leon Wang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.