Рекомендация 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"
uniq
фильтрует только смежные строки. Скажем, у вас есть такой файл:
$ cat foobar.txt
foo
bar
foo
с двумя не -смежными foo
строками. Затем uniq -c
считает каждую из них один раз, в то время как сортировка файла сначала означает, что uniq -c
видит их как соседние и считает их одной строкой, которая появляется дважды:
$ uniq -c foobar.txt
1 foo
1 bar
1 foo
$ sort foobar.txt | uniq -c
1 bar
2 foo