Desejo verificar sistemas de arquivos somente leitura. Eu escrevi este awk
comando e funciona bem:
awk '{ if ( $4 ~ /ro,/ && $2 !~ /sys/ ) {print $2} }' /proc/mounts
Eu quero usar este comando com ssh
. Isso não funciona:
$ ssh ip "awk '{ if ( $4 ~ /ro,/ && $2 !~ /sys/ ) {print $2} }' /proc/mounts"
bash: !~: event not found
Como posso fazer isso? O problema é por causa do caractere til?
O caractere til não é o culpado, o ponto de exclamação é.
Aspas duplas
!~
acionam a substituição do histórico em seu shell local. Observe que as aspas simples internas não importam localmente (compare esta situação semelhante; as aspas internas serão importantes no shell remoto).Você precisa fazer
!~
aparecer aspas simples para o shell local. O problema é que você também deseja aspas simples no shell remoto. Por esse motivo, você não pode aninhar citações facilmente.Você pode desabilitar a substituição do histórico em seu shell local
set +H
e usar aspas duplas localmente. Mas observe que você não deseja ser expandido por nenhum shell, incluindo o local$4
.$2
Portanto, você precisa colocar aspas simples localmente de qualquer maneira; ou para escapar$
com\
, por exemplo\$2
.Escapar com
\
pode ajudar na substituição de histórico indesejada apenas com unquoted\!
. Aspas duplas\!
impedirão a substituição do histórico, mas isso\
não desaparecerá, isso quebrará as coisas mais tarde.Abordagens possíveis:
Sem aspas e com escape
!
:Substituição de histórico desabilitada:
Aspas simples em tudo, exceto as aspas simples internas que serão cruciais no shell remoto:
Aspas simples em tudo localmente, aspas duplas no shell remoto. Isso enviará seus problemas para o shell remoto, portanto, você precisará lidar com eles de qualquer maneira:
Surpresa! Escapamos ,
$
mas não!~
; e não háset +H
, mas o comando funciona.Isso ocorre porque
ssh
gera um shell não interativo no lado remoto. O Bash não interativo começa com a expansão do histórico desativada por padrão (observe que o shell remoto pode ou não ser o Bash em primeiro lugar, pode ou não suportar o histórico). Isso faz com que o problema principal desapareça. O mesmo mecanismo o ajudaria se você executasse seussh
comando original de forma não interativa, por exemplo, em um script local (embora você ainda precisasse de$
caracteres de escape).Para mim, parece que o bash está pré-interpretando o ! como parte de sua funcionalidade de histórico.
Você já tentou escapar do ! com \ ? Veja Como escapar caracteres pelo comando SSH em um Makefile