【问题标题】:Shell script cut returning empty stringShell 脚本剪切返回空字符串
【发布时间】:2016-04-20 02:35:08
【问题描述】:

我正在编写一个脚本,我正在尝试获取 linux 发行版。我有以下代码,但它返回一个空字符串。我确定我错过了什么

OS=`cat /etc/os-release | grep -sw NAME`
NEWOS=$OS | `cut -d \" -f2`

echo $NEWOS 

【问题讨论】:

    标签: sh


    【解决方案1】:

    你有两个问题。

    1. 仅输入 $OS 不会将任何内容输出到标准输出(通过管道传输到 cut)。

    2. 您的第二个问题是您将cut 放在反引号中。这意味着您正在尝试运行空剪辑的输出。

    解决办法是写$(echo "$OS" | cut -d \" -f2)

    【讨论】:

    • ++,但为了培养良好习惯,我建议 (a) 不要使用全大写名称(例如,$os 而不是 `$OS),以及 (b) 使用双引号变量引用。
    • 这是少数几个引号无关紧要的情况之一,所以我没有包括它们,但你对良好实践的看法是正确的。我已经编辑了它们。
    【解决方案2】:

    就像 Honesty 的回答所说,你有两个问题。除了他的回答之外,我还想解决在您的代码中使用反引号的问题。

    命令替换可以通过两种方式完成,一种是使用$(command),另一种是`command`。两者的工作方式相同,但$(command) 表单是现代的方式,并且更清晰易读。

    $(...) 的真正优势不是可读性(我想说,这是一个品味问题),而是能够嵌套命令替换不转义,并且不必担心另外必须逃避$\ 实例。 - mklement0

    以下代码使用现代方式:

    #!/bin/bash
    
    OS=$(cat /etc/os-release | grep -sw NAME)
    
    NEWOS=$(echo "$OS" | cut -d \" -f2)
    
    echo $OS
    echo $NEWOS
    

    在我的电脑上输出:

    NAME="Ubuntu"
    Ubuntu
    

    【讨论】:

    • @mklement0 快速问题:我在编辑之前的原始答案是,$() 是 POSIX 标准的一部分。但我不确定,所以我编辑了答案的那部分。 $() 是 POSIX 标准的一部分吗?哦,如果我将您的评论添加到我的答案中,您介意吗?
    • 是的,反引号现在已被弃用。
    • 但实际上你可以嵌套反引号; Jonny 关于$() 的存在是正确的,其存在只是为了便于阅读。尝试运行echo `echo \`echo foo\``
    • @JonnyHenly:$(...)`...` 都是 POSIX 标准的一部分 - 请参阅 pubs.opengroup.org/onlinepubs/9699919799/utilities/…
    • @Honesty:你错过了一个重要的含义:弃用经常 - 尽管不一定 - 是删除功能的前兆,它这里显然不是这样。只要我们同意引用的段落说“仅在简单情况下使用此功能,在复杂情况下避免使用它”而不是“此功能已过时,它可能会消失”,我们总体上是一致的。
    【解决方案3】:

    使用单个awk 命令补充替代方法解决问题的现有有用答案:

    os=$(awk -F\" '/^NAME=/ { print $2 }' /etc/os-release)
    echo "$os"
    

    请注意,我已将变量的大小写从OS 更改为os,因为最好不要使用全大写的shell 变量名称来更改avoid conflicts with environment variables and special shell variables

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-14
      • 2017-08-06
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多