Có thể gửi HEREDOC qua ssh đến một máy chủ từ xa từ bên trong một tập lệnh chạy cục bộ không?


8

Về cơ bản, tôi muốn chạy một tập lệnh trên máy A, nó sẽ SSH vào máy B, thực thi các lệnh trên B và trả lại đầu ra cho máy A.

Vì vậy, tôi đang tạo một kịch bản csh để làm điều này, hy vọng, nếu nó có thể.

Chẳng hạn, giải pháp từ câu trả lời này hoạt động từ dòng lệnh:

ssh user@host << 'ENDSSH'
ls -l
ENDSSH

Tôi có thể xác minh nó đang chạy ls trên remote chứ không phải cục bộ.

Tuy nhiên tôi muốn có thể làm điều này trong backticks, bên trong tập lệnh csh của tôi chạy cục bộ. Điều đó có thể không?

Tôi biết có thể SSH vào và chạy một tập lệnh trên điều khiển từ xa, nhưng đó không phải là trường hợp của tôi.

Tôi cũng đã nghe nói có thể gửi một tập lệnh thứ hai được lưu trữ cục bộ qua SSH (mà tôi cũng chưa tìm ra), nhưng tôi thích ý tưởng có tất cả các lệnh bên trong tập lệnh gốc, do đó là HEREDOC.

Tôi biết đó là một câu hỏi khá đặc biệt, nhưng nếu có một cách, nó sẽ rất tuyệt để biết làm thế nào.

Những thứ không hoạt động

1)

`ssh user@host<<'ENDSSH'`
`echo "ls -l"`
`echo "ENDSSH"`

Điều này đưa ra lỗi:

stty: standard input: Invalid argument. stty: standard input: Invalid argument. Warning: Command not found

Và sau đó nó chạy ls -lcục bộ, và sau đó nó cố chạy ENDSSHcục bộ và tất nhiên không thành công với lệnh không tìm thấy.

2)

`ssh user@host<<'ENDSSH'`
echo "ls -l"
echo "ENDSSH"

Vấn đề tương tự như trên, ngoại trừ nó chỉ hiển thị ls -lENDSSHdưới dạng văn bản. Có nghĩa là ... vì phần HEREDOC không thành công.

3) 3-5 không chính xác những gì tôi đã hỏi, nhưng vẫn cố gắng để làm cho ngay cả trường hợp cơ bản hoạt động.

`ssh user@host ls-l` 

Điều này trả về total: Command not found. Yeah, tôi không biết nơi đó đến từ đâu.

4)

`cat ./test.csh | ssh user@host`

Cũng trả về giống như lần thử số 1

5)

`cat ./test.csh | ssh -t user@host`

Tương tự như # 1 và 4.

Tôi bắt đầu sử dụng hết các giải pháp khác từ stackoverflow / Ubuntu / serverfault ... vv. Hầu hết mọi người hỏi về cách chạy tập lệnh của họ trên một điều khiển từ xa từ dòng lệnh, chứ không phải làm thế nào để chạy các lệnh trên một điều khiển từ một tập lệnh đang chạy cục bộ.

Biên tập

Vâng, tôi nghĩ rằng tôi có một phần của vấn đề đã tìm ra. Ví dụ với trường hợp 3 ở trên, những gì xảy ra được ls -lchạy cục bộ và phần đầu tiên của đầu ra sau đó được gửi qua SSH dưới dạng một lệnh.

Tôi nhận thấy điều này bởi vì tôi đã cố gắng ssh user@host $CMD, với $CMDthiết lập "whoami". Đầu ra là username: Command not found, và sau đó tôi nhận ra totallà từ đầu ra ls. Vẫn không chắc chắn về cách giải quyết điều này, mặc dù


Bạn đã thử chưa Tôi chủ yếu sử dụng scp && ssh để kiểm tra bất kỳ vấn đề nào với kết nối hoặc khóa mật khẩu / ssh. Tuy nhiên giải pháp của bạn có vẻ ổn.
Archemar

@Archemar Xem phần cuối tôi đã thêm.
krb686

Chỉnh sửa nhận xét của bạn, điều đó không thực sự chính xác. Bạn có trường hợp 3 là `` `ssh user @ host ls -l`` `. Những gì nó làm là chạy ssh user@host ls -l, mà lần lượt chạy ls -ltrên máy chủ từ xa. Đầu ra kết quả được lấy bởi các backticks và được đánh giá cục bộ, bởi vì không có gì để thu thập đầu ra đó, cuối cùng được thực thi như một lệnh cục bộ.
roaima 3/03/2015

@roaima Được rồi, vì vậy tôi đã chuyển nó xung quanh, vì vậy nó chạy ls -ltừ xa và đầu ra cục bộ, trái ngược với ls -lcục bộ và đầu ra từ xa?
krb686 3/03/2015

Vâng đúng vậy.
roaima

Câu trả lời:


4

Nếu bạn bọc toàn bộ lệnh mà bạn muốn thực hiện bên trong backticks, có khả năng bạn sẽ có được giải pháp chính xác. Có những vấn đề liên quan đến việc đánh giá các biến và các yếu tố nội suy khác, nhưng tôi sẽ đặt chúng sang một bên trong giây lát.

Tuy nhiên, tôi không hoàn toàn chắc chắn lý do tại sao bạn muốn bất cứ điều gì trong backticks. Câu hỏi của bạn nói rằng bạn muốn chạy một tập lệnh cục bộ từ xa. Ví dụ đầu tiên của bạn làm điều này.

ssh -q user@host << ENDSSH
hostname
ls -l
id
ENDSSH

Có lẽ bạn muốn nhận đầu ra của việc thực hiện từ xa thành một biến? Nó không nói rằng bất cứ nơi nào trong Câu hỏi, nhưng bạn sẽ làm như thế này ( bash)

RESULT=$(ssh user@host <<ENDSSH
hostname
id
ENDSSH
)
...
echo "$RESULT"

Hoặc, kể từ khi bạn đề cập csh, như thế này

set result = `ssh -q user@host` <<ENDSSH
hostname
id
ENDSSH
...
echo "$result"

Lưu ý rằng đối với cshbiến thể, tất cả các dòng đầu ra được nối với nhau.

Tôi thấy rằng bạn đã báo cáo lỗi, stty: standard input: Invalid argument.Điều này có thể xảy ra vì bạn có một sttylệnh trong tập lệnh đăng nhập của mình trên máy chủ từ xa. Điều này nên được bọc trong một thử nghiệm cho một vỏ tương tác. Trong bashbạn sẽ làm một cái gì đó như thế này:

if test -n "$PS1"
then
    # Interactive setup here
    stty ...
fi

1
Vâng, bạn đã đúng, cuối cùng tôi sẽ muốn lưu trữ kết quả của các lệnh chạy trên điều khiển từ xa bên trong các biến trong tập lệnh chạy cục bộ. cshThật không may, giải pháp của bạn không hoạt động. Điều này vẫn dẫn đến lỗi : stty: standard input: Invalid argument. Tôi đã thêm một chỉnh sửa vào câu hỏi của tôi ở cuối với một số thông tin thú vị, không chắc bạn đã thấy chưa, nhưng có một manh mối.
krb686 3/03/2015

1
@ krb686 Vui lòng xem cập nhật cho stty. Nếu bạn có tùy chọn, tôi thực sự khuyên bạn nên ngừng viết cshtập lệnh và sử dụng sh/ bashthay vào đó. Có một số vấn đề quan trọng khi sử dụng cshlàm ngôn ngữ kịch bản, vì vậy nó thực sự có lợi cho bạn để học sh/ bash, ngay cả khi bạn thích cshsử dụng tương tác.
roaima 3/03/2015

Ah tôi đã không nhìn thấy điều đó. Tôi sẽ kiểm tra xem trong một phút nữa. Cảm ơn
krb686 3/03/2015

2

Không chắc chắn những gì bạn đang cố gắng để làm, nhưng đây là một cái gì đó làm việc cho tôi.

(drat gặp sự cố giữ cho trình soạn thảo văn bản stackexchange không xử lý các dấu tick phía sau như định dạng các ký tự, sử dụng các ký tự chuyển tiếp cho ý nghĩa của dấu tick ngược)

R='ssh -t hostname <<EOF
ls -l
EOF'

Lưu ý rằng tôi không đóng backtick cho đến sau EOF và sử dụng tùy chọn -t để tạo TTY ảo mặc dù stdio đang được chuyển hướng.


1
Hmm, vì vậy, đầu vào của heredoc cần phải nằm trong backtick. Bây giờ làm cách nào để tách các lệnh đó trong di truyền trên các dòng riêng biệt của tập lệnh csh? Điều này chỉ phàn nàn về việc thiếu backtick, vì backtick được bắt đầu trên dòng đầu tiên trước ssh và kết thúc sau EOF
krb686 3/03/2015

Được rồi, vì vậy bạn cần một "\"ở cuối mỗi dòng để tiếp tục di truyền. Thật thú vị, điều này gần như hoạt động. Nó phàn nàn với : ls: cannot access EOF: No such file or directory. Nó nghĩ rằng đó EOFlà một đối số cho bất kỳ lệnh nào trước nó. Cũng đã thử điều này với whoamivà nó nóiwhoami: extra operand EOF
krb686

@roaima Cảm ơn, tôi đã được nghe ở nhiều nơi. Nếu bạn có một tài liệu tham khảo tốt, tôi muốn đọc nó! Tôi đã học (và thích) bash, nhưng tôi có khả năng bị buộc phải sử dụng cshcho một số thứ. Mặc dù vậy, tôi không hoàn toàn chắc chắn về điều đó và nếu có cách nào để thực hiện thành công điều này bash, tôi chắc chắn cũng sẽ thích thông tin đó, nếu có ai có nó
krb686 3/03/2015

@ krb686 chúng tôi không thể di chuyển ý kiến. Chỉ cần xóa nó và đăng lại ở đúng nơi.
terdon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.