tra-loi-cau-hoi-phat-trien-web.com

Làm cách nào để sử dụng SSH để chạy tập lệnh Shell trên máy từ xa?

Tôi phải chạy tập lệnh Shell (windows/Linux) trên máy từ xa.

Tôi đã cấu hình SSH trên cả máy A và B. Tập lệnh của tôi nằm trên máy A sẽ chạy một số mã của tôi trên máy từ xa, máy B.

Các máy tính cục bộ và từ xa có thể là hệ thống dựa trên Windows hoặc Unix.

Có cách nào để chạy làm điều này bằng cách sử dụng plink/ssh không?

1120
Arun

Nếu Máy A là hộp Windows, bạn có thể sử dụng Plink (một phần của PuTTY ) với tham số -m và nó sẽ thực thi tập lệnh cục bộ trên máy chủ từ xa.

plink [email protected] -m local_script.sh

Nếu Máy A là một hệ thống dựa trên Unix, bạn có thể sử dụng:

ssh [email protected] 'bash -s' < local_script.sh

Bạn không cần phải sao chép tập lệnh vào máy chủ từ xa để chạy tập lệnh.

1100
Jason R. Coombs

Đây là một câu hỏi cũ và câu trả lời của Jason hoạt động tốt, nhưng tôi muốn thêm vào đây:

ssh [email protected] <<'ENDSSH'
#commands to run on remote Host
ENDSSH

Điều này cũng có thể được sử dụng với su và các lệnh yêu cầu đầu vào của người dùng. (lưu ý ' thoát heredoc)

Chỉnh sửa: Vì câu trả lời này tiếp tục nhận được một chút lưu lượng truy cập, tôi sẽ thêm nhiều thông tin hơn nữa vào cách sử dụng tuyệt vời này của heredoc:

Bạn có thể lồng các lệnh với cú pháp này và đó là cách duy nhất lồng nhau dường như hoạt động (theo cách lành mạnh)

ssh [email protected] <<'ENDSSH'
#commands to run on remote Host
ssh [email protected] <<'END2'
# Another bunch of commands on another Host
wall <<'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH

Bạn thực sự có thể có một cuộc trò chuyện với một số dịch vụ như telnet, ftp, v.v. Nhưng hãy nhớ rằng heredoc chỉ gửi stdin dưới dạng văn bản, nó không chờ phản hồi giữa các dòng

Chỉnh sửa: Tôi vừa phát hiện ra rằng bạn có thể thụt lề bên trong bằng tab nếu bạn sử dụng <<-END!

ssh [email protected] <<-'ENDSSH'
    #commands to run on remote Host
    ssh [email protected] <<-'END2'
        # Another bunch of commands on another Host
        wall <<-'ENDWALL'
            Error: Out of cheese
        ENDWALL
        ftp ftp.secureftp-test.com <<-'ENDFTP'
            test
            test
            ls
        ENDFTP
    END2
ENDSSH

(Tôi nghĩ rằng điều này sẽ làm việc)

Đồng thời xem http://tldp.org/LDP/abs/html/here-docs.html

560
Yarek T

Ngoài ra, đừng quên thoát các biến nếu bạn muốn chọn chúng từ Máy chủ đích.

Điều này đã bắt tôi ra trong quá khứ.

Ví dụ:

[email protected]> ssh [email protected] "echo \$HOME"

in ra/nhà/người dùng2

trong khi

[email protected]> ssh [email protected] "echo $HOME"

in ra/nhà/người dùng

Một vi dụ khac:

[email protected]> ssh [email protected] "echo hello world | awk '{print \$1}'"

in ra "xin chào" chính xác.

230
dogbane

Đây là phần mở rộng cho câu trả lời của YarekT để kết hợp các lệnh từ xa nội tuyến với việc chuyển các biến ENV từ máy cục bộ sang Máy chủ từ xa để bạn có thể tham số hóa các tập lệnh của mình ở phía xa:

ssh [email protected] ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote Host
  echo $ARG1 $ARG2
ENDSSH

Tôi thấy điều này đặc biệt hữu ích bằng cách giữ tất cả trong một tập lệnh để nó rất dễ đọc và có thể duy trì.

Tại sao điều này hoạt động. ssh hỗ trợ cú pháp sau:

người dùng ssh @ Host remote_command

Trong bash, chúng ta có thể chỉ định các biến môi trường để xác định trước khi chạy lệnh trên một dòng như vậy:

ENV_VAR_1 = 'value1' ENV_VAR_2 = 'value2' bash -c 'echo $ ENV_VAR_1 $ ENV_VAR_2'

Điều đó giúp dễ dàng xác định các biến trước khi chạy lệnh. Trong trường hợp này echo là lệnh của chúng tôi đang chạy. Tất cả mọi thứ trước khi echo xác định các biến môi trường.

Vì vậy, chúng tôi kết hợp hai tính năng đó và câu trả lời của YarekT để có được:

người dùng ssh @ Host ARG1 = $ ARG1 ARG2 = $ ARG2 'bash -s' << 'ENDSSH' ...

Trong trường hợp này, chúng tôi đang đặt ARG1 và ARG2 thành giá trị cục bộ. Gửi tất cả mọi thứ sau khi người dùng @ Host làm remote_command. Khi máy từ xa thực thi lệnh ARG1 và ARG2 được đặt các giá trị cục bộ, nhờ đánh giá dòng lệnh cục bộ, xác định các biến môi trường trên máy chủ từ xa, sau đó thực hiện lệnh bash -s bằng các biến đó. Voila.

142
chubbsondubs
<hostA_Shell_Prompt>$ ssh [email protected] "ls -la"

Điều đó sẽ nhắc bạn nhập mật khẩu, trừ khi bạn đã sao chép khóa công khai của máy chủ lưu trữ của bạn vào tệp ủy quyền trên thư mục của thư mục người dùng. Điều đó sẽ cho phép xác thực không mật khẩu (nếu được chấp nhận là phương thức xác thực trên cấu hình của máy chủ ssh)

98
Vinko Vrsalovic

Tôi đã bắt đầu sử dụng Fabric cho các hoạt động phức tạp hơn. Fabric yêu cầu Python và một vài phụ thuộc khác, nhưng chỉ trên máy khách. Máy chủ chỉ cần là một máy chủ ssh. Tôi thấy công cụ này mạnh hơn nhiều so với các tập lệnh Shell được truyền cho SSH và rất đáng để cài đặt (đặc biệt nếu bạn thích lập trình bằng Python). Fabric xử lý các tập lệnh đang chạy trên nhiều máy chủ (hoặc máy chủ của một số vai trò nhất định), giúp tạo điều kiện cho các hoạt động bình thường (chẳng hạn như thêm một dòng vào tập lệnh cấu hình, nhưng không phải nếu nó đã có) và cho phép xây dựng logic phức tạp hơn (như Python ngôn ngữ có thể cung cấp).

26
Jason R. Coombs

Hãy thử chạy ssh [email protected] sh ./script.unx.

10
Jeremy

Giả sử bạn có nghĩa là bạn muốn thực hiện điều này tự động từ máy "cục bộ", mà không cần đăng nhập thủ công vào máy "từ xa", bạn nên xem xét một tiện ích mở rộng TCL có tên là Expect, nó được thiết kế chính xác cho loại tình huống này. Tôi cũng đã cung cấp một liên kết đến một tập lệnh để đăng nhập/tương tác thông qua SSH.

https://www.nist.gov/service-resource/software/Exect

http://bash.cyberciti.biz/security/Exect-ssh-login-script/

9
George Jempty

Tôi sử dụng tập lệnh này để chạy tập lệnh Shell trên máy từ xa (đã thử nghiệm trên/bin/bash):

ssh [email protected] . /home/deploy/path/to/script.sh
2
Is Ma

Câu trả lời ở đây ( https://stackoverflow.com/a/2732991/4752883 ) hoạt động rất tốt nếu bạn đang cố chạy tập lệnh trên máy linux từ xa bằng cách sử dụng plink hoặc ssh. Nó sẽ hoạt động nếu tập lệnh có nhiều dòng trên linux.

** Tuy nhiên, nếu bạn đang cố chạy tập lệnh bó nằm trên máy linux/windows cục bộ và máy từ xa của bạn là Windows và nó bao gồm nhiều dòng sử dụng **

plink [email protected] -m local_script.bat

sẽ không làm việc.

Chỉ dòng đầu tiên của tập lệnh sẽ được thực thi. Đây có lẽ là một hạn chế của plink.

Giải pháp 1:

Để chạy tập lệnh bó đa dòng (đặc biệt nếu nó tương đối đơn giản, bao gồm một vài dòng):

Nếu tập lệnh bó ban đầu của bạn như sau

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

bạn có thể kết hợp các dòng với nhau bằng cách sử dụng dấu tách "&&" như sau trong tệp local_script.bat của bạn: https://stackoverflow.com/a/8055390/4752883 :

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

Sau khi thay đổi này, bạn có thể chạy tập lệnh như được chỉ ra ở đây bởi @ JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883 với:

`plink [email protected] -m local_script.bat`

Giải pháp 2:

Nếu tập lệnh bó của bạn tương đối phức tạp, có thể tốt hơn là sử dụng tập lệnh bó đóng gói lệnh plink cũng như được chỉ ra ở đây bởi @Martin https://stackoverflow.com/a/32196999/4852883 :

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
1
alpha_989

nếu bạn muốn thực thi lệnh như thế này thì lệnh temp=`ls -a` echo $temp trong `` sẽ gây ra lỗi.

lệnh dưới đây sẽ giải quyết vấn đề này ssh [email protected] ''' temp=`ls -a` echo $temp '''

1
Jinmiao Luo
cat ./script.sh | ssh <user>@<Host>
0
Amir

Tập lệnh bash này ssh vào một máy từ xa đích và chạy một số lệnh trong máy từ xa, đừng quên cài đặt kỳ vọng trước khi chạy nó (trên mac brew install expect)

#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh  [email protected]$hosts
expect "[email protected]$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"
0
Mohammed Rafeeq
ssh [email protected] ".~/.bashrc;/cd path-to-file/;.filename.sh"

rất khuyến khích tìm nguồn tệp môi trường (.bashrc/.bashprofile/.profile). trước khi chạy một cái gì đó trong Máy chủ từ xa vì các biến môi trường của máy chủ đích và nguồn có thể bị lỗi.

0
Ankush Sahu