Про поводження з довільними аргументами
Якщо ви дійсно використовуєте лише один рядок, тобто -time Aug 18 18
, тоді ви можете просто жорсткий код, і наявні відповіді підказують, як це зробити адекватно. З іншого боку, якщо вам потрібно передати невідомі аргументи (наприклад, повідомлення, яке відображатиметься в іншій системі, або ім’я файлу, створеного там, де кінцеві користувачі можуть контролювати його ім’я), тоді потрібно більше уваги.
З bash
або ksh
як/bin/sh
Якщо ваш пульт /bin/sh
надається bash або ksh, ви можете сміливо виконувати наступні дії з ненадійним списком аргументів, таким чином, що навіть шкідливі імена (наприклад $(rm -rf $HOME).txt
) можуть бути передані як аргументи безпечно:
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"
}
З будь-яким сумісним POSIX /bin/sh
Щоб бути захищеним від досить зловмисних даних аргументів (намагання скористатись цитуванням, що не відповідає POSIX, використовуваним printf %q
у bash, коли недруковані символи присутні у рядку, що виводиться), навіть із тим, /bin/sh
що є базовою лінією POSIX (наприклад, dash
або ash
), це виходить трохи цікавіше:
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
}
Використання (для будь-якого з перерахованих вище)
Функції, наведені вище, можуть бути викликані як:
# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18
... або ...
# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"