sshpass -p 'password' ssh user@192.168.3.3 "some_cmd $(printf '%q ' "$@")" sshpass -p 'password' ssh user@192.168.3.3 "f() for i; do some_cmd "$i"; done; f $(printf '%q ' some_cmd "$@")"
Согласно справочной странице sshpass,
sshpass [-ffilename | -dnum | -ppassword | -e] [параметры] аргументы команды
Таким образом, вы должны иметь возможность передавать все
«$ @»
в команду ssh, например:sshpass -p 'password' ssh user@192.168.3.3 printf '%q\n' "$@"
Поскольку ваша целевая команда может не быть имея возможность обрабатывать такую обработку аргументов, мы можем взломать это:
sshpass -p 'password' 'k(){ for i; do echo $i; done; }; k' "$@"
Давайте протестируем с некоторыми пробелами ...
set -- 'foo bar' $'lorem\nipsum\td' # paste that two lines.. Since I don't have sshpass installed, just using ssh.
ssh
явно напортачил. Давайте подключим какую-нибудь фальшивую оболочку и посмотрим, что произошло ...#!/bin/bash # /bin/mysh # someone:x:1000:1000:FOo,,Bar,:/home/foo:/bin/mysh printf '%q ' bash "$@"; echo; exec bash -xv --norc "$@";
Хмм. Давай попробуем.
bash -c $'printf %q\\n foo bar lorem\nipsum\td' printf %q\n foo bar lorem + printf %qn foo bar lorem ipsum d + ipsum d bash: line 1: ipsum: command not found
Очевидно, ssh просто объединил эти вещи вместе с пробелами. Не круто.
Давайте заранее избавимся от этого на нашей стороне с помощью
printf '% q'
, и вы получите TL; Ответ DR . Теперь вы можете выяснить, что такое ошибка EOF и-c
.Примечание: я не уверен, что ssh по-разному выполняет параметр -c в разных версиях. Возможно, вам придется попробовать это самостоятельно. По крайней мере, это верно для OpenSSH 7.1 ( ssh.c: 955-969 ).
Если вы знаете , что в конце значения $wfpd
есть символ, который вам нужно удалить, и если вы используете bash
или zsh
или busybox sh
¹, то вы можете сделать
wfpd="${wfpd:0:-1}"
Это удалит последний символ из значения переменной, независимо от того, что это такое. Это расширение подстроки, специфичное для упомянутых оболочек, которое расширяется до значения символа от нуля до последнего символа в строке минус один.
¹ 1.28.0 или новее, а также при сборке с ENABLE_HUSH_BASH_COMPAT
для hush
, ENABLE_ASH_BASH_COMPAT
дляash
(по умолчанию)
С помощью ksh93
, zsh
или bash
вы можете использовать :
wfpd=${wfpd//[^[:digit:]-]}
Чтобы удалить все символы, кроме 0123456789 -, из содержимого$wfpd
(при условии, что это десятичные целые числа, вам необходимо адаптироваться к числам с плавающей запятой или шестнадцатеричным числам... ).
Для POSIX можно использовать:
wfpd=${wfpd%%[![:digit:]-]*}
для удаления части $wfpd
, начинающейся с первого символа, отличного от 0123456789 -или:
wfpd=${wfpd%"${wfpd##*[[:digit:]]}"}
, чтобы удалить все после последней десятичной цифры.
Вместо выполнения:
wfpd=$(cat < file)
Вы также можете:
IFS=$'\r' read wfpd rest_ignored < file
Который считывал бы первую строку файла до первой \r
в $wfpd
, даже не создавая новый процесс и не выполняя команду.
В качестве альтернативы можно удалить из имени переменной все, кроме цифр. Если имя переменной сохранено в файле с именем file.txt
, то:
cat file.txt
wfpd=$'16213\r'
cat file.txt | sed 's/[^0-9]*//g'
16213
Вы можете использовать расширение параметра, чтобы удалить замыкающий \r
. %
означает "удалить с конца значения".
wfpd=$'16213\r'
wfpd=${wfpd%$'\r'}
((wfpd == 16213)) || echo Wrong