【问题标题】:fish shell command subsitution in watch commandwatch 命令中的 fish shell 命令替换
【发布时间】:2019-08-08 16:36:06
【问题描述】:

我正在尝试在 fish shell 中使用 watch 命令。

sudo watch -d "lsof -a -p (pidof myprogram)"

如您所见,鱼的这个有效命令替换语法。但是当我运行它时,我在watch 中收到以下错误。

sh: -c: line 0: syntax error near unexpected token '('
sh: -c: line 0: `lsof -a -p (pidof myprogram)'

如果我将命令更改为 sh 兼容语法

sudo watch -d "lsof -a -p $(pidof myprogram)"

我收到以下错误。

$(...) is not supported. In fish, please use '(pidof)'.                                                                                                                        
fish: sudo watch -d "lsof -a -p $(pidof myprogram)"

有没有办法解决这个问题?

【问题讨论】:

  • 我很难理解为什么fish 应该关心看起来像另一种语言语法的数据。如果发生用户期望的命令替换,当然发出警告,但将其视为错误?
  • 这是一个语法错误,因为$() 是无效的语法。这是因为否则人们会尝试$() 并使用文字$() 获取命令执行,所以告诉他们他们最有可能尝试的方法不起作用会更安全。解决方法是单引号,就像你说的那样。

标签: shell terminal fish


【解决方案1】:

简而言之:

sudo watch -d "lsof -a -p "(pidof myprogram)

即退出引号并进行命令替换(中间没有空格,因此将直接附加)。

这里有一点差距,因为您希望命令的输出根本不被拆分 - 在这里它将在换行符上拆分它,并生成多个标记,如 "lsof -a -p "line1 "lsof -a -p"line2。在这种情况下,这应该不是问题,但如果你愿意,你应该使用string split0 like

 sudo watch -d "lsof -a -p "(pidof myprogram | string split0)

只会拆分 NULL 字节,这在命令行参数中是不允许的(这是通用的 unix 事物 - 因为 main 的参数作为 NULL 分隔的字符串传递,没有任何其他长度指示,如果它们包含 NULL,它们将被截断)。

【讨论】:

    【解决方案2】:

    watch 将使用sh 执行shell 命令。您可以将字符串用单引号引起来,以防止 fish 对用于不同 shell 的数据感到恐慌。

    sudo watch -d 'lsof -a -p $(pidof myprogram)'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多