【问题标题】:Does variable=$(...) store the command or the result of the command in POSIX shvariable=$(...) 是否将命令或命令的结果存储在 POSIX sh 中
【发布时间】:2021-01-15 06:29:01
【问题描述】:

我想知道:当我例如打电话

list=$(ps -ax)

是 ps -ax 执行一次,我可以多次读取该值,或者是每次调用 $list 时执行的命令

【问题讨论】:

  • 为什么要在这里提问?你可以自己用三行来回答这个问题:time=$(date +%s); echo "$time"; sleep 1; echo "$time"
  • @CharlesDuffy 这正是我所做的,见下文。计划是回答自己的问题,以便其他人找到这个解决方案。不知道,为什么这没有被标记为已解决 O_o
  • 在允许接受自我回答之前有一个超时,但您最终应该能够接受它。也就是说,我们收到了很多基于人们预期相反行为的问题,因此知识库中肯定已经存在重复。
  • OTOH,将那些作为this的副本关闭更有意义,因为它是明确询问的。

标签: shell sh posix


【解决方案1】:

解决方案是存储结果。 为了测试这一点,我使用了以下脚本

    #!/bin/sh
    myTime=$(date)
    for a in 1 2 3 4
    do
        echo 'Stored command: '$myTime
        echo 'Fresh command: '$(date)
        sleep 2
    done 

结果如下所示:

Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:44 +02 2020
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:46 +02 2020
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:48 +02 2020
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:50 +02 2020

随意添加缺失的标签;不知道如何让 $() 之类的东西对搜索引擎最友好

【讨论】:

    【解决方案2】:

    POSIX sh 保证命令不会被重新执行,见下文。

    小心通过经验测试得出关于 POSIX sh 的结论。例如,如果您计时sleep 60 | true,您会发现 bash、ksh、zsh 和 dash 都需要 60 秒。但是,POSIX sh 仍然允许它立即完成。


    Spec for $():

    shell 应通过在子 shell 环境中执行命令来扩展命令替换(参见 Shell 执行环境)并将命令替换(命令文本加上封闭的“$()”或反引号)替换为命令。

    when it's applied:

    当需要执行给定的简单命令时 [...] 以下扩展、赋值和重定向都应从命令文本的开头到结尾执行:

    [...]

    1. 在分配值之前,应针对波浪号扩展、参数扩展、命令替换、算术扩展和引号删除对每个变量赋值进行扩展。

    [...]

    变量赋值应按如下方式进行:

    如果没有得到命令名,变量赋值会影响当前的执行环境。

    由于$() 被替换为命令的文本,并且这发生在分配变量之前,因此保证不会在符合 POSIX 的 sh 实现中重新执行命令。

    【讨论】:

      【解决方案3】:

      引用 bash 手册页:

      Command Substitution
          Command substitution allows the output of a com-
          mand to replace the command name. There are two forms:
              $(command)
          or
              `command`
      

      所以存储的是命令的输出,而不是命令本身。 如果要存储一个每次都求值的命令,需要使用eval

      #!/bin/bash
      
      command="date"
      startTime=$(date)
      for i in `seq 1 4`
      do
          echo "$i: $startTime - " $(eval $command)
          sleep 1
      done
      

      【讨论】:

      • 你的答案是关于 bash,问题是关于 POSIX sh。 (调整标题以使其更清晰)我没有看到重复
      • 除了标签之外,原始问题没有表明任何关于 POSIX 的内容。 OTOH 引用的 bash 手册页没有将该行为标记为特定于 bash。此外,我的回答至少添加了需要做的事情,如果您不希望存储结果,而是每次都执行存储的命令。
      猜你喜欢
      • 2019-08-06
      • 2012-06-21
      • 2020-08-14
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 2018-06-27
      • 2013-10-14
      • 2022-10-19
      相关资源
      最近更新 更多