【问题标题】:Using "while read" and "for i in" resulting in ambiguous redirect使用“while read”和“for i in”导致重定向不明确
【发布时间】:2016-08-25 06:58:52
【问题描述】:
# while read a b ; do echo $a $b ; done < `for i in \`cat users.txt\` ; do PHPVER=\`selectorctl --user-current --user=$i\` ; echo $i $PHPVER ; done | awk '{print $1, $2}' | sed 's/native/5.3/g'`

-bash: `for i in \`cat users.txt\` ; do PHPVER=\`selectorctl --user-current --user=$i\` ; echo $i $PHPVER ; done | awk '{print $1, $2}' | sed 's/native/5.3/g'`: ambiguous redirect

如果去掉while read语句,输出:

# for i in `cat users.txt` ; do PHPVER=`selectorctl --user-current --user=$i` ; echo $i $PHPVER ; done | awk '{print $1, $2}' | sed 's/native/5.3/g'

user1 5.4
user2 5.4
user3 5.3

所以我需要获取这两列并将每一列转换为一个变量,这样我就可以在这样的命令中运行它们:

# selectorctl --set-user-current=$b --user=$a

但是,当我添加 while read 语句时,它会引发模棱两可的重定向

【问题讨论】:

  • 首先,使用$( . . . ) 代替反引号(` . . . `)。它使嵌套更容易 - 无需使用 \` 之类的东西
  • & 你的&lt; $(for ...) 应该改为&lt; &lt;(for ...)
  • 如果# 提示意味着您以root 身份运行,那么这样做是个坏主意。以 root 身份进行实验是双重的坏主意。当你不打算这样做时,你可能会造成伤害。

标签: linux bash for-loop while-loop


【解决方案1】:
while read -r user; do
    phpver=$(selectorctl --user-current --user="$user")
    output="$user $phpver"
    echo "${output//native/5.3}" | awk '{print $1, $2}'
done < users.txt

awk 的放置在这里是否可以,或者是否有更合适的方法从输出中删除多余的行,在这种情况下是:

user 5.4    5.4.45  /opt/alt/php54/usr/bin/php-cgi

但我需要

user 5.4

【讨论】:

  • ...你有一堆引用错误,shellcheck.net 会发现。
  • 我更正了引号,至于 for 语句,我得稍微弄乱一下。
  • (...另外,通常不需要通过管道将 awk 连接到其他任何东西 - awk 可以完成 sed 可以做的所有事情,并且 [从文本处理的角度来看] bash 本身可以做的任何事情) .
【解决方案2】:

目前还不清楚您要做什么。你可能想做类似的事情

while read -r user; do
    read phpver rest < <(selectorctl --user-current --user="$user")
    output="$user $phpver"
    echo "${output//native/5.3}"
done < users.txt

Don't use for to read lines from a file.

【讨论】:

  • 很遗憾我一直在使用 for 来读取文件,只是我从来没有新的习惯是不正确的。 echo "${output//native/5.3}" 如何用 5.3 替换 native,我以为你总是必须使用 sed 之类的东西来替换。我试过谷歌搜索//但它是可以做替换的回声还是?对此超级困惑 此外,selectorctl --user-current --user="$user" 的输出提供的不仅仅是 2 个单词,例如:user 5.5 5.5.34 /opt/alt/php55/usr/bin/php- cgi 这就是我使用 awk 的原因。我可以“awk”那个 echo 语句中的前 2 个单词 $1 $2 吗?
  • @JCats :阅读mywiki.wooledge.org/BashGuide/Parameters(参数替换)中的~第三部分以获取有关${var//targ/repl} 的信息。说句公道话,它是相当晦涩的,但是 shell 的一个非常强大的特性。祝你好运。
  • @JCats,在您的问题中包含该详细信息会很好。更新。这是一个进程替换:你可以在 bash 手册中阅读它。
  • @glenn jackman 你介意我问一下你所做的更改是如何让它只输出前两个单词的吗?我了解 $user 但是 $phpver 如何只在以下情况下显示第一个单词: selectorctl --user-current --user="$user" 给你 3
  • read 命令拆分文本并将单词分配给给定的变量名称。我给了 2 个 varnames 来阅读:第一个词进入 phpver,所有其他词进入 rest
猜你喜欢
  • 2022-10-25
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
相关资源
最近更新 更多