工作 bash 命令在函数或别名中中断

Working bash command breaks when in function or alias

当我 运行 此命令以交互方式输出预期的日志名称(最后修改,每个服务名称文件)。

# Gets last active service log in a /environmentsDir/serviceName/var/output/logs directory. You need to cd 1st.
ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'

当我尝试为别名表达式或函数转义它时,无法正确处理,总是因不同原因而失败。

在 CLI 中转义它以使函数或别名正常工作的正确方法是什么?

例如,如果我想跟踪那个日志文件,函数或别名应该允许我:

lastLog=escaped(ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}')

tail -f $(lastLog)

编辑:

添加尝试函数的输出:

21:55:28-user@host:/environmentsDir/env/serviceName/var/output/logs$ ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'
serviceName.2022-04-12-21
21:55:33-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog() {
logbash: syntax error near unexpected token `('
21:55:42-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog() { \
logbash: syntax error near unexpected token `('
21:55:46-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog { \
> ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'
head: invalid option -- 't'
Try 'head --help' for more information.
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
21:56:10-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog() { ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'; }
logbash: syntax error near unexpected token `('
21:56:41-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog() { ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'; }^C
21:56:56-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog() {ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}' ; }
logbash: syntax error near unexpected token `('
21:57:14-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog { ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}' ;  }
logbash: syntax error near unexpected token `}'

# This one doesn't blow up but still fails when executed:
21:57:35-user@host:/environmentsDir/env/serviceName/var/output/logs$ function lastLog { ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}' ;  }
21:57:47-user@host:/environmentsDir/env/serviceName/var/output/logs$ lastLog 
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

第二次编辑:

@john-kugelman 的回答是正确的,我已经试过了,没有成功。增加的问题是,正如@gordon-davisson 在下面的评论中所指出的,我添加了一个与函数同名的别名,它获得了优先级并且也被破坏了。

函数的好处在于它们不需要任何特殊的转义。只需将命令完全按照写在函数中的方式放置即可:

lastLog() {
    ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'
}

您可以像这样在交互式 shell 中键入 multi-line 函数定义。但是如果你想要它作为一个 one-liner,它会是这样的,在右大括号之前附加一个 semi-colon 到命令:

lastLog() { ls -tl | head -n20 | grep $(basename $(pwd | egrep '/environmentsDir/env/[^\/]+' -o)) | head -n1 | awk '{print $(NF)}'; }

可以使用 shell 的参数扩展来简化您的函数:

lastLog() {
  local dirname=${PWD#/environmentDir/env/}     # remove the prefix
  dirname=${dirname%%/*}                        # remove the suffix

  ls -tl *"$dirname"* | head -n1
}