【问题标题】:Read file and run command in zsh在 zsh 中读取文件并运行命令
【发布时间】:2021-01-12 16:12:13
【问题描述】:

所以我通常会创建包含命令列表的作业文件。然后我就这样执行它

cat jobFile | while read a; do $a; done

这在 bash 中总是有效的。但是,我刚刚开始在显然使用 zsh 的 Mac 上工作。这个命令失败了,“没有这样的文件”等等。我已经通过手动运行几行来测试作业文件,所以应该没问题。

我发现有关 zsh 读取的问题,但它们往往是从变量中读取的,例如$a=('a' 'b' 'c') 或 echo $a

感谢您的回答!

【问题讨论】:

  • 如果是命令列表,您应该在bashzsh 中都使用. jobFile。您可能被zsh 默认情况下不对未引用的参数扩展执行分词这一事实所困扰。如果a="foo bar",则$a 尝试运行名为foo bar 的命令,而不是名为foo 的带有参数bar 的命令。
  • 感谢您的回复@chepner。你能详细说明一下吗?你是什​​么意思只使用 . jobFile ?您的意思是删除 cat 命令并使用 .相反还是别的什么?你能举个例子吗?对不起,noobishness!
  • 您似乎假设文件的每一行都是一个完整的 shell 命令,在这种情况下,文件本身就是一个 shell 脚本。 . jobFile 完全符合您的要求:它一个接一个地执行每个命令,但您让 shell 正确解析和评估每个命令,而不是依赖于参数扩展技巧。
  • @chepner 哦,好的,我现在知道了!谢谢!基本上只是直接将其作为 shell 脚本执行。谢谢!
  • 仅仅因为 Mac 使用 zsh 作为其默认的交互式 shell,并不意味着您必须在脚本中使用它。将#!/bin/bash放在脚本的开头,它将使用bash

标签: bash zsh


【解决方案1】:

bash 中,未加引号的参数扩展总是会进行分词,因此如果a="foo bar",则$a 会扩展为两个词,foobar。作为命令,这意味着运行带有参数bar 的命令foo

zsh 中,参数扩展为not 默认情况下会进行分词,这意味着相同的扩展$a 会产生一个单词foo bar,将其视为命令的名称执行。

在任何一种情况下,依靠参数扩展来“解析”一个shell命令都是脆弱的;除了分词之外,扩展还受路径名扩展(通配)的影响,并且您仅限于简单的命令及其参数。不允许使用管道、列表(&&||)或重定向,因为所有内容都将被视为命令名称和一系列参数。

您想要在 both shell 中简单地将您的作业文件视为一个 shell 脚本,可以使用 . 命令在当前 shell 中执行:

. jobFile

【讨论】:

    【解决方案2】:

    您为什么要以如此繁琐的方式执行它?假设jobFile 是一个包含一系列 bash 命令的文件,您可以简单地将其运行为

    bash jobFile
    

    如果它包含一系列 zsh 命令,你同样可以运行它

    zsh jobFile
    

    如果您采用这种方法,我会在作业文件的名称中反映它的用途,即,

    bash jobFile.bash
    zsh jobFile.zsh
    

    而且,如果您编写一个作业文件以使其与任一 shell 兼容,我将其命名为 jobFile.sh

    【讨论】:

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