使用命令的 SSH 不作为别名运行

使用命令的 SSH 不作为别名运行

我有以下命令可以远程访问本地服务器以及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)'"

在最后一种形式中,所有在双引号($,`\)中保留特殊含义的字符都必须被转义(这里我们只有一个$)。

相反,你的函数应该可以正常工作。

相关内容