我想检查只读文件系统。我写了这个awk
命令,它工作正常:
awk '{ if ( $4 ~ /ro,/ && $2 !~ /sys/ ) {print $2} }' /proc/mounts
我想将此命令与ssh
. 这不起作用:
$ ssh ip "awk '{ if ( $4 ~ /ro,/ && $2 !~ /sys/ ) {print $2} }' /proc/mounts"
bash: !~: event not found
我怎样才能做到这一点?问题是因为波浪号吗?
波浪号不是罪魁祸首,感叹号才是。
双引号
!~
触发本地 shell 中的历史记录替换。请注意,内部单引号在本地无关紧要(比较这种情况,类似的情况;内部引号在远程 shell 中很重要)。您需要
!~
为本地 shell 显示单引号。问题是您还希望在远程 shell 中使用单引号。因此,您不能轻松嵌套引号。您可以在本地 shell 中禁用历史记录替换,
set +H
并坚持在本地使用双引号。但请注意,您不希望$4
或被$2
任何外壳扩展,包括本地外壳。因此,无论如何您都需要在本地进行单引号;或逃脱$
,\
例如\$2
。转义 with
\
可以帮助仅使用 unquoted 替换不需要的历史记录\!
。双引号\!
将防止历史替换,但这\
不会消失,它会在以后破坏。可能的方法:
未引用和转义
!
:禁用历史替换:
单引号除内部单引号外的所有内容,这在远程 shell 中至关重要:
在本地单引号,在远程 shell 中双引号。这会将您的问题推送到远程 shell,因此无论如何您都需要处理它们:
惊喜!我们逃脱了
$
,但没有!~
;并且没有set +H
,但该命令有效。这是因为在远
ssh
程端生成了一个非交互式shell。非交互式 Bash 默认情况下禁用历史扩展(请注意,远程 shell 可能首先是也可能不是 Bash,它可能完全支持也可能不支持历史)。这使得主要问题消失了。如果您以ssh
非交互方式运行原始命令,例如在本地脚本中(尽管您仍然需要转义$
字符),相同的机制将对您有所帮助。对我来说,bash 似乎正在预先解释 ! 作为其历史功能的一部分。
你有没有试过逃避!和 \ ?请参阅 如何在 Makefile 中通过 SSH 命令转义字符