ฉันจะรันสคริปต์ทุบตีท้องถิ่นบนเครื่องระยะไกลผ่าน ssh ได้อย่างไร


51

ฉันกำลังมองหาวิธีที่จะผลักดันการกำหนดค่าจากเครื่องกลางหนึ่งไปยังเครื่องระยะไกลหลายเครื่องโดยไม่จำเป็นต้องติดตั้งอะไรบนเครื่องระยะไกล

เป้าหมายคือการทำสิ่งที่คุณจะพบกับเครื่องมือที่ชอบcfengineแต่ในชุดของเครื่องจักรที่ไม่มีตัวแทนตั้งค่า นี่อาจเป็นเทคนิคที่ดีในการตั้งค่าcfagentในชุดเครื่องระยะไกลที่มีอยู่


ที่คล้ายกันกับ SO: stackoverflow.com/q/305035/435605
AlikElzin-kilaka

1
คำถามที่เกิดขึ้นจริงมี 23 upvote ที่ซ้ำกันบน SO มี 55: P
MoJo

คำตอบ:


55

คุณสามารถส่งสคริปต์และให้สคริปต์ทำงานแบบ ephemerally ได้โดยการวางสคริปต์ไว้ในนั้นและสั่งงานเชลล์

เช่น

echo "ls -l; echo 'Hello World'" | ssh me@myserver /bin/bash

โดยธรรมชาติแล้วชิ้น"ls -l; echo 'Hello World'"ส่วนจะถูกแทนที่ด้วยสคริปต์ทุบตีที่เก็บไว้ในไฟล์บนเครื่องท้องถิ่น

เช่น

cat script.sh | ssh me@myserver /bin/bash

ไชโย!


2
ฉันจะทำให้การทำงานนี้เป็น sudo บน remote system.eg ได้อย่างไรถ้าฉันเข้าสู่ระบบเซิร์ฟเวอร์ระยะไกลฉันมักจะเรียกใช้งานนี้เป็น sudo -u testuser script.sh
Sharjeel

จะทำอย่างไรถ้าสคริปต์ที่ฉันโทรเกี่ยวข้องกับการโต้ตอบของผู้ใช้ ???
Abhimanyu Srivastava

20

มีหลายวิธีที่จะทำ

1:

ssh user@remote_server 'bash -s' < localfile

2:

cat localfile  | ssh user@remote_server

3:

ssh user@remote_server "$(< localfile)"

หมายเลข 3 เป็นวิธีที่ฉันชอบ su -S service nginx restart

(# 1 จะใช้สคริปต์ที่เหลือเป็นอินพุตสำหรับคำถามรหัสผ่านเมื่อคุณใช้su -S)


4
เกี่ยวกับการรันสคริปต์โลคัลบนเครื่องระยะไกล - มีวิธีการส่งตัวแปรเป็นอาร์กิวเมนต์ไปยังเครื่องระยะไกล .. หรือไม่? เช่นพร้อมกับสคริปต์ฉันต้องการส่งตัวแปร (มีหลายบรรทัด) เป็นอาร์กิวเมนต์ไปยังเครื่องระยะไกล สคริปต์ตั้งใจจะใช้ตัวแปร

13

ฉันจะแนะนำ python Fabric เพื่อจุดประสงค์นี้:

#!/usr/bin/python
# ~/fabfile.py

from fabric_api import *

env.hosts = ['host1', 'host2']
def deploy_script():
    put('your_script.sh', 'your_script.sh', mode=0755)
    sudo('./your_script.sh')

# from shell
$ fab deploy_script

คุณควรจะสามารถใช้ข้างต้นเพื่อเริ่มต้น ศึกษาเอกสารที่ยอดเยี่ยมของ Fabric เพื่อใช้เวลาที่เหลือ ในฐานะที่เป็นภาคผนวกคุณสามารถเขียนสคริปต์ของคุณได้อย่างสมบูรณ์แบบในเนื้อผ้า - ไม่จำเป็นต้องคัดลอก แต่ควรสังเกตว่าการเปลี่ยนสคริปต์บนเครื่องทั้งหมดคุณจะต้องแก้ไขสำเนาในเครื่องและปรับใช้งานซ้ำ นอกจากนี้ด้วยการใช้งานพื้นฐานมากกว่า API เล็กน้อยคุณสามารถแก้ไขสคริปต์ตามโฮสต์ที่กำลังทำงานอยู่และ / หรือตัวแปรอื่น ๆ มันเป็นความคาดหวังแบบ pythonic


ฉันไม่คิดว่านี่จะตอบคำถามได้อย่างแน่นอน แต่ฉันชอบความคิดนี้และฉันเห็นว่า Fabric เป็นเครื่องมือที่มีประโยชน์
tremoloqui

1
@tremoloqui Fabric เป็นเครื่องห่อหุ้มงูหลามรอบ ssh - ไม่จำเป็นต้องติดตั้งบนเครื่องเป้าหมายบันทึกสคริปต์ที่ถูกผลัก ซึ่งหากเขียนใหม่เป็นชุดคำสั่ง Fabric (โดยใช้runและsudo) ไม่จำเป็นต้องมีแม้แต่
Izkata

5

นี่คือสิ่งที่ Ansible ใช้สำหรับ ไม่มีเอเจนต์คุณเพียงแค่สร้างไฟล์ข้อความชื่อ:

/etc/ansible/hosts

ด้วยเนื้อหาที่มีลักษณะดังนี้:

[webhosts]
web[1-8]

นี่จะระบุว่าเครื่อง "web1, web2 ... web8" อยู่ในกลุ่ม "webhosts" จากนั้นคุณสามารถทำสิ่งต่าง ๆ เช่น:

ansible webhosts -m service -a "name=apache2 state=restarted" --sudo

เพื่อเริ่มบริการ apache2 บนทุกเครื่องของคุณโดยใช้ sudo

คุณสามารถทำตามคำสั่งการบินเช่น:

ansible webhosts -m shell -a "df -h"

หรือคุณสามารถเรียกใช้สคริปต์ท้องถิ่นบนเครื่องระยะไกล:

ansible webhosts -m script -a "./script.sh"

หรือคุณสามารถสร้าง playbook (ค้นหาเอกสารสำหรับรายละเอียด) ด้วยการกำหนดค่าที่สมบูรณ์ที่คุณต้องการให้เซิร์ฟเวอร์ของคุณสอดคล้องและปรับใช้กับ:

ansible-playbook webplaybook.yml

โดยทั่วไปคุณสามารถเริ่มใช้มันเป็นเครื่องมือบรรทัดคำสั่งสำหรับการเรียกใช้คำสั่งบนเซิร์ฟเวอร์หลายเครื่องและขยายการใช้งานเป็นเครื่องมือกำหนดค่าแบบสมบูรณ์ตามที่เห็นสมควร


3
ฉันชอบ ansible มากพอ ๆ กับผู้ชายคนต่อไป แต่ถ้าเขาถามเกี่ยวกับสคริปต์แล้ว ansible ก็มีโมดูลสคริปต์ที่ดีจริงๆ:ansible webhosts -m script script.sh
ptman

1
คำตอบอื่น ๆ ทั้งหมดเกี่ยวข้องกับสคริปต์ทุบตี แต่ไม่ใช่สิ่งที่เขาถามโดยเฉพาะ เขาเพิ่งพูดว่ากดการกำหนดค่าไปยังเครื่องระยะไกล แต่พูดถึงดีของโมดูลสคริปต์ :)
seumasmac

กรุณาโหวตคำตอบนี้! นี่คือวิธีที่จะทำ!
ลูกไก่

@ptman ฉันเพิ่งสังเกตว่าในขณะที่เขาไม่ได้พูดถึงสคริปต์ในคำถามเขาทำในชื่อ! ขอโทษ ฉันได้อัพเดทแล้ว
seumasmac

3

ตามที่อธิบายไว้ในคำตอบนี้คุณสามารถใช้heredoc :

ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH

คุณต้องระวัง heredoc เพราะมันแค่ส่งข้อความ แต่มันไม่ได้รอการตอบสนองจริงๆ นั่นหมายความว่ามันจะไม่รอให้คำสั่งของคุณถูกดำเนินการ


1

คำตอบที่นี่ ( https://stackoverflow.com/a/2732991/4752883 ) ทำงานที่ดีถ้าคุณกำลังพยายามที่จะเรียกใช้สคริปต์บนเครื่องลินุกซ์ระยะไกลโดยใช้หรือplink มันจะทำงานถ้าสคริปต์ที่มีหลายสายsshlinux

** อย่างไรก็ตามหากคุณพยายามที่จะเรียกใช้สคริปต์แบทช์ที่อยู่บนlinux/windowsเครื่องท้องถิ่นและเครื่องระยะไกลของคุณWindowsและมันประกอบด้วยหลายบรรทัดโดยใช้ **

plink root@MachineB -m local_script.bat

มันจะไม่ทำงาน

บรรทัดแรกของสคริปต์เท่านั้นที่จะถูกเรียกใช้งาน นี่อาจจะเป็นข้อ จำกัด plinkของ

โซลูชันที่ 1:

ในการรันสคริปต์แบตช์หลายบรรทัด (โดยเฉพาะถ้าค่อนข้างง่ายประกอบด้วยสองสามบรรทัด):

หากสคริปต์แบตช์ดั้งเดิมของคุณมีดังต่อไปนี้

cd C:\Users\ipython_user\Desktop 
python filename.py

คุณสามารถรวมบรรทัดเข้าด้วยกันโดยใช้ตัวคั่น "&&" ดังต่อไปนี้ในlocal_script.batไฟล์ของคุณ ดังต่อไปนี้ https://stackoverflow.com/a/8055390/4752883 :

cd C:\Users\ipython_user\Desktop && python filename.py

หลังจากการเปลี่ยนแปลงนี้คุณสามารถเรียกใช้สคริปต์ตามที่ได้อธิบายไว้ที่นี่โดย @ JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883

โซลูชันที่ 2:

หากสคริปต์ชุดงานของคุณค่อนข้างซับซ้อนอาจเป็นการดีกว่าถ้าคุณใช้สคริปต์ชุดงานซึ่งสรุปคำสั่ง plink และตามที่อธิบายไว้ที่นี่โดย @Martin https://stackoverflow.com/a/32196999/4752883 :

rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N

rem Wait a second to let Plink establish the tunnel 
timeout /t 1

rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R

rem Kill the tunnel
taskkill /im plink.exe

0

ทำไมไม่คัดลอกสคริปต์ก่อนแล้วจึงเรียกใช้

scp your_script.sh the_server:
ssh the_server "chmod +x your_script.sh; ./your_script.sh"

แน่นอนคุณควรระวังไม่ให้อัปโหลดไปยังสถานที่ที่เขียนได้ทั่วโลกดังนั้นจึงไม่มีใครสามารถคลี่คลายได้ก่อนที่คุณจะเรียกใช้ (อาจเป็นรูท)


1
เหตุผลที่ฉันไม่ต้องการอัปโหลดสคริปต์ก็ไม่จำเป็นต้องจัดการและมีความเสี่ยงที่คุณกล่าวถึง นอกจากนี้ดูเหมือนว่าสำหรับฉันมันง่ายกว่ากระบวนการหลายขั้นตอนในการอัปโหลดการประมวลผลและ (ทางเลือก) การลบ
tremoloqui

0

เขียนสคริปต์ใหม่ในลักษณะที่แต่ละคำสั่งในคำสั่งนั้นมีคำนำหน้าด้วย ssh และชื่อโฮสต์ / ip หรือรายการดังกล่าวจะถูกส่งผ่านไปยังสคริปต์เป็นอาร์กิวเมนต์ (สมมติว่าคุณมีการตั้งค่าการรับรองความถูกต้องคีย์รหัสผ่าน งานบางอย่างอาจจำเป็นต้องส่งรหัสข้อผิดพลาด / ส่งคืนกลับจากคำสั่งระยะไกลอย่างถูกต้อง ...


0

หากสคริปต์ไม่ใหญ่เกินไปและคุณกำลังใช้ bash หรือ ksh ...

ssh vm24 -t bash -c "$(printf "%q" "$(< shell-test.sh )")"

ทั้ง stdin และ stdout ทำงานได้อย่างถูกต้อง แต่สคริปต์ถูก จำกัด ไว้ที่ขนาดอาร์กิวเมนต์ (ปกติประมาณ 100k) อาร์กิวเมนต์ของสคริปต์อาจใช้งานได้ในตอนท้ายของบรรทัดซึ่งอาจเป็นไปตามอาร์กิวเมนต์ "-" พิเศษ "-t" เพื่อจัดสรร pty เป็นตัวเลือก

ระวัง: นี่จะทำให้การทุบตีเสร็จสิ้นไม่ต้องกด Tab

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.