Làm cách nào để thực thi tập lệnh cục bộ trên máy từ xa và bao gồm các đối số?


116

Tôi đã viết một kịch bản chạy tốt khi được thực thi cục bộ:

./sysMole -time Aug 18 18

Các đối số "-time" , "Aug" , "18""18" được chuyển thành công vào kịch bản.

Bây giờ, tập lệnh này được thiết kế để được thực thi trên một máy từ xa, nhưng, từ một thư mục cục bộ trên máy cục bộ. Thí dụ:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole

Điều đó cũng hoạt động tốt. Nhưng vấn đề phát sinh khi tôi cố gắng đưa vào những lý lẽ đã nói ở trên ( ví dụ: ngày 18 tháng 8 ngày 18 tháng 8) , ví dụ:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18

Sau khi chạy tập lệnh đó, tôi gặp lỗi sau:

bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell

Xin vui lòng cho tôi biết những gì tôi đang làm sai, điều này rất bực bội.


1
"Bash -s" là một trong những cách bạn có thể thực thi tập lệnh từ đầu vào tiêu chuẩn (ví dụ: một tệp).
AllenD

Câu trả lời:


160

Bạn đã khá gần với ví dụ của bạn. Nó chỉ hoạt động tốt khi bạn sử dụng nó với các đối số như thế này.

Kịch bản mẫu:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Ví dụ hoạt động:

$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye

Nhưng nó thất bại cho các loại đối số:

$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...

Chuyện gì đang xảy ra vậy?

Vấn đề bạn gặp phải là đối số -time, hoặc --timetrong ví dụ của tôi, đang được hiểu là một chuyển đổi sang bash -s. Bạn có thể bình định bashbằng cách chấm dứt nó khỏi việc lấy bất kỳ đối số dòng lệnh nào còn lại cho chính nó bằng cách sử dụng --đối số.

Như thế này:

$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18

Ví dụ

# 1:

$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye

# 2:

$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye

# 3:

$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye

#4:

$ ssh  < ./ex.bash serverA "bash -s -- --time bye"
--time bye

LƯU Ý: Chỉ cần làm rõ rằng bất cứ nơi nào chuyển hướng xuất hiện trên dòng lệnh sẽ không có sự khác biệt, vì sshdù sao hãy gọi một vỏ từ xa với sự kết hợp các đối số của nó, trích dẫn không tạo ra nhiều khác biệt, trừ khi bạn cần trích dẫn trên vỏ từ xa như trong ví dụ # 4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>

4
bạn là một thiên tài! Tôi phải làm gì để đạt đến trình độ của bạn? Tôi có rất nhiều công việc cắt ra. Cám ơn rất nhiều.
AllenD

14
@ ALLenD - chỉ cần tiếp tục đặt câu hỏi, và thử và tham gia trên trang web nhiều nhất có thể. Tôi luôn cố gắng và học hỏi một cái gì đó mới mỗi ngày. Trước câu hỏi của bạn, tôi cũng không biết làm thế nào. số 8-). Cảm ơn câu hỏi của bạn!
slm

5
lưu ý chuyển hướng có thể xuất hiện ở bất kỳ điểm nào trong lệnh: ví dụ bash -s -- --time bye < ./ex.bashhoặc thậm chí < ./ex.bash bash -s -- --time bye. điều này là do shell trước tiên thực hiện lệnh chuyển hướng (bất kể nó nằm ở đâu trong lệnh), sau đó thiết lập chuyển hướng, sau đó thực hiện phần còn lại của dòng lệnh với chuyển hướng tại chỗ.
lesmana

@sim Tôi đang cố gắng thực hiện chính xác điều này, nhưng từ trong một tập lệnh, không phải từ dòng lệnh. Bất kỳ ý tưởng làm thế nào để làm điều này? Vì một số lý do, kèm theo câu trả lời chính xác của bạn trong backticks hoàn toàn không hoạt động. Thay vào đó, nó chạy tập lệnh được chỉ định cục bộ và đầu ra được gửi dưới dạng lệnh tới bash over ssh
krb686

@ krb686 - Tôi sẽ hỏi nó như một Q. mới
slm

5

Về xử lý các lý lẽ tùy tiện

Nếu bạn thực sự chỉ sử dụng một chuỗi, tức là. -time Aug 18 18, sau đó bạn có thể chỉ cần mã hóa nó và các câu trả lời hiện có cho bạn biết cách thực hiện điều đó một cách đầy đủ. Mặt khác, nếu bạn cần chuyển các đối số không xác định thông qua (như một thông báo sẽ được hiển thị trên hệ thống khác hoặc tên của tệp được tạo trong đó người dùng cuối có thể kiểm soát tên của nó), thì cần phải cẩn thận hơn.


Với bashhoặc kshnhư/bin/sh

Nếu điều khiển từ xa của bạn /bin/shđược cung cấp bởi bash hoặc ksh, bạn có thể thực hiện các thao tác sau một cách an toàn với danh sách đối số không đáng tin cậy, sao cho ngay cả các tên độc hại (như $(rm -rf $HOME).txt) có thể được chuyển qua làm đối số một cách an toàn:

runRemote() {
  local args script

  script=$1; shift

  # generate eval-safe quoted version of current argument list
  printf -v args '%q ' "$@"

  # pass that through on the command line to bash -s
  # note that $args is parsed remotely by /bin/sh, not by bash!
  ssh user@remote-addr "bash -s -- $args" < "$script"
}

Với bất kỳ POSIX-tuân thủ /bin/sh

Để an toàn trước dữ liệu đối số đủ độc hại (cố gắng tận dụng trích dẫn không tuân thủ POSIX được sử dụng printf %qtrong bash khi các ký tự không thể in được xuất hiện trong chuỗi được thoát) ngay cả với một /bin/shđường cơ sở-POSIX (như dashhoặc ash), nó trở nên thú vị hơn một chút:

runRemote() {
  local script=$1; shift
  local args
  printf -v args '%q ' "$@"
  ssh user@remote-addr "bash -s" <<EOF

  # pass quoted arguments through for parsing by remote bash
  set -- $args

  # substitute literal script text into heredoc
  $(< "$script")

EOF
}

Cách sử dụng (cho một trong những điều trên)

Các hàm được đưa ra ở trên có thể được gọi là:

# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18

...hoặc là...

# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"

-3

nói aa là một tệp cục bộ có chứa ls

$ssh servername "cat | bash" < a.a

thay đổi 127.0.0.1 thành bất cứ thứ gì ip từ xa của bạn

cả hai đưa ra một thông điệp về phân bổ giả nhưng chúng hoạt động.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

Hoặc là

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a


2
Tôi đang đấu tranh để xem câu hỏi này trả lời bao xa.
ChrisWue

Chất lượng và định dạng là đáng ngờ. Tôi cũng không thấy bất kỳ thông tin hữu ích mới nào không có trong câu trả lời được chấp nhận.
Julie Pelletier

@JuliePelletier Tôi đã đưa ra một số ví dụ về 'con mèo' không có trong câu trả lời được chấp nhận. Thật tốt khi biết những cách khác để làm việc.
barlop

Đó không phải là một điều tốt; mèo của bạn là vô dụng.
Scott

2
Ôi Chúa ơi. Tôi đã bỏ qua liên kết đến việc sử dụng mèo vô dụng vì tôi cho rằng bây giờ mọi người ít nhất đã nghe đến cụm từ này; rõ ràng đó là một giả định xấu về phía tôi.
Scott
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.