Вы можете сделать что-то вроде следующего в bash
, zsh
или ksh
:
SECONDS=0
while command
do sleep "$((10-(SECONDS%10)))"
done
Вот что говорится в руководстве bash
о $SECONDS
:
$SECONDS
- При каждом обращении к этому параметру возвращается количество секунд с момента вызова оболочки. Если параметру
$SECONDS
присвоено значение, то при последующих обращениях возвращается количество секунд с момента присвоения плюс присвоенное значение. Если$SECONDS
будетсброшен
, он потеряет свои специальные свойства, даже если впоследствии будет сброшен.
Вот рабочий пример:
( SECONDS=0
while sleep "$((RANDOM%10))"
do sleep "$((10-(SECONDS%10)))"
echo "$SECONDS"
done
)
10
20
30
40
50
60
70
80
90
100
Ваша работа была бы намного проще, если бы вы просто создали сценарий в другой системе, который делал то, что вы хотели, а затем вызвали этот сценарий без каких-либо параметров. Альтернативой является создание сценария на другой стороне, который показывает, какие параметры он получает, что-то вроде echo _args.sh:
#!/bin/ksh
echo "$0 $@"
ARG=1
while [ $# -gt 0 ]
do
echo "$ARG: $1"
shift
(( ARG++ ))
done
Тогда вы можете позвонить:
ssh tomcat@rmgdmzwebapp02.dmz.local bin/echo_args.sh -f -u \'INFORMATION \\[main\\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \\[\\\"ajp-nio-8009\\\"\\]\' /opt/tomcat/logs/catalina.out
и вы получите:
bin/echo_args.sh -f -u INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\] /opt/tomcat/logs/catalina.out
1: -f
2: -u
3: INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]
4: /opt/tomcat/logs/catalina.out
, который показывает, что параметры правильно поступают на другую сторону. Теперь вы просто заменяете echo _args.sh своей розничной программой:
ssh sshuser@my-server.net.bar /bin/retail -f -u \'INFORMATION \\[main\\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \\[\\\"ajp-nio-8009\\\"\\]\' /opt/tomcat/logs/catalina.out
Рекомендация Jaken551 близка к фактическому решению, но немного отличается из-за дополнительного уровня вложенной цитаты. Давайте сначала посмотрим, что происходит с этим.
Моя обычная техника для этого состоит в том, чтобы просто поставить echo
перед командой (это не идеально, но обычно достаточно хорошо ).
# Your original command which you say works locally
$ echo 'INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]' /opt/tomcat/logs/catalina.out
INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\] /opt/tomcat/logs/catalina.out
# The command though ssh
$ ssh example.com echo "INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]" /opt/tomcat/logs/catalina.out
INFORMATION [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler [ajp-nio-8009] /opt/tomcat/logs/catalina.out
# The command through ssh with the quotes
$ ssh example.com 'echo "INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]" /opt/tomcat/logs/catalina.out'
INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \["ajp-nio-8009"\] /opt/tomcat/logs/catalina.out
Итак, обратите внимание на разницу в результатах. В обеих версиях ssh
экранирование отличается.
Что происходит в первом ssh
примере, так это то, что первый уровень цитаты удаляется локальной оболочкой, затем ssh
получает несколько аргументов (echo
, INFORMATION \[main\]...
), которые затем объединяются вместе в один аргумент echo INFORMATION \[main\]...
, который затем оценивается через оболочку на удаленной стороне как sh -c 'echo INFORMATION \[main\]...'
.
Во втором примере ssh
первый уровень цитирования снова удаляется локальной оболочкой, поэтому ssh получает echo "INFORMATION \[main\]..."
, который затем оценивается на удаленной стороне как sh -c 'echo "INFORMATION \[main\]..."'
. Так что это немного лучше, но вы все еще имеете дело с двумя уровнями оболочек, удаляющих ваши цитаты и экраны.
Это можно сделать двумя способами. Во-первых, вместо этого передать вашу команду на STDIN, что гарантирует, что ваша команда будет обработана оболочкой только один раз, во время фактического выполнения :
.ssh -T example.com <<'EOF'
echo 'INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]' /opt/tomcat/logs/catalina.out
EOF
INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\] /opt/tomcat/logs/catalina.out
Однако это означает, что удаленная команда не имеет доступа к вашему TTY или STDIN, поэтому, если команде требуется STDIN, она не будет работать.
Второй подход заключается в том, чтобы оболочка добавила для вас дополнительный уровень цитаты.
$ CMD="$(printf "%q " echo 'INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]' /opt/tomcat/logs/catalina.out)"
$ ssh example.com "$CMD"
INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\] /opt/tomcat/logs/catalina.out
(вам не нужен посредник $CMD
, и вы можете сделать встроенный ssh... "$(printf "%q "...)"
,Я просто сделал это отдельно для разборчивости)
TL;DR :Любой из следующих вариантов вам подойдет:
ssh -T sshuser@my-server.net.bar <<'EOF'
/bin/retail -f -u 'INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]' /opt/tomcat/logs/catalina.out
EOF
CMD="$(printf "%q " /bin/retail -f -u 'INFORMATION \[main\] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler \[\"ajp-nio-8009\"\]' /opt/tomcat/logs/catalina.out)"
ssh sshuser@my-server.net.bar "$CMD"