我有以下命令可以远程访问本地服务器以及tail -f
我拥有的应用程序的最新日志文件。
该命令在命令行中运行得非常好 -
ssh user@hostname 'tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'
问题是,当我将其设为别名(甚至是函数)时,它会评估ls -1r
本地计算机上的完成情况,并尝试将其传递到远程计算机。
alias latestbotlogs="ssh user@hostname 'tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'"
function latestbotlogs {
ssh user@hostname 'tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'
}
我需要使用什么语法才能在我通过 SSH 访问的远程计算机上评估整个命令。
提前致谢!
答案1
对于别名,您需要一些转义
alias latestbotlogs="ssh user@hostname 'tail -f \\\$\\(ls -1r \\~/Development/python/twitter-bot/logs/*.log \\| head -1\\)'"
或者
alias latestbotlogs='ssh user@hostname '\''tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'\'
第二个版本更容易,您不必考虑必须引用的所有运算符。
该函数应该按原样工作。
答案2
正确处理有点复杂的引号转义的另一种方法:
alias botlogs='ssh user@host "ls -r ~/whatever/*log | head -1 | xargs tail -f"'
# if (selected) filename contains backslash or quotemark(s)
# need -d'\n' on GNU and I don't know good solution on other
# this also fails if filename contains whitespace, but so did $( )
尽管我同意该函数应该在没有任何黑客行为的情况下工作,并且一般来说函数更加一致和灵活,并且比别名更好。
PS:当ls
输出通过管道传输(或重定向)时,它始终使用 1 列格式,这里不需要-1
。
答案3
您可以通过将用单引号括起来的字符串分配给 来设置别名latestbotlogs
,如下所示:
alias latestbotlogs='ssh user@hostname '\''tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'\'
其中表达式\'
用于保护 shell 中的单引号并将它们连接到结果命令中。您可以验证它们是否已保留:
$ alias latestbotlogs
alias latestbotlogs='ssh user@hostname '\''tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'\'''
使用您的别名时:
alias latestbotlogs="ssh user@hostname 'tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'"
命令替换根据定义立即进行评估。发生这种情况是因为单引号在转义(用\
)或用双引号( )括起来时失去了其特殊含义"
。 (参考:引用见“The Open Group 基本规范第 7 期,2018 年版”)。
这就是关键:当别名是时,远程命令周围的单引号足以保护它调用,但不要阻止当别名为时替换所包含的命令已创建。
您还可以使用"'"
以下替代方法\'
:
alias latestbotlogs='ssh user@hostname '"'"'tail -f $(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'"'"
或者将整个命令用双引号引起来并添加一些转义:
alias latestbotlogs="ssh user@hostname 'tail -f \$(ls -1r ~/Development/python/twitter-bot/logs/*.log | head -1)'"
在最后一种形式中,所有在双引号($
,`
和\
)中保留特殊含义的字符都必须被转义(这里我们只有一个$
)。
相反,你的函数应该可以正常工作。