【问题标题】:Linux extract values from bash sciptLinux 从 bash 脚本中提取值
【发布时间】:2017-04-16 14:19:51
【问题描述】:

我正在尝试编写一个 bash 脚本,但是有一个问题 - 我在 do-done 之外看不到变量的内容。有什么帮助吗?

#!/bin/bash

file="ip.txt"

while IFS=: read -r f1 f2 f3
do
     printf '%s %s %s\n' "$f1" "$f2" "$f3"
done <"$file"

printf '%s %s %s\n' "$f1" "$f2" "$f3"

echo -e "iptables -t nat -A PREROUTING -p tcp --dport $f2 -j DNAT --to-destination $f1:$f3"

输出>

192.168.0.1  
2000  
1000  

iptables -t nat -A PREROUTING -p tcp --dport  -j DNAT --to-destination :

【问题讨论】:

  • 你能检查你的输出吗?我认为192.168.0.1 2000 1000 3 个值在一行上。
  • read 在最终读取时将每个变量分配给空字符串。该空值对您的脚本完全可见! (只是不是特别有用)

标签: bash shell init


【解决方案1】:

问题不是文件末尾有一个空行,因此 $f1 $f2 $f3 在循环的最后一次迭代中变为空吗?

【讨论】:

  • 在这种情况下,1000iptables.... 之间不应该有 两个 空输出行吗?第一个空输出行来自循环内的printf,其中读取了所谓的空输入行,第二个空输出行来自循环后的printf
  • @voyvoda:要验证 JohanThomsen 提出的想法,请将循环内的 printf 更改为 printf 'f1=%s f2=%s f3=%s\n' "$f1" "$f2" "$f3" 之类的内容,以便在输入为空时更好地查看
【解决方案2】:

我可以看到你的问题

while IFS=: read -r f1 f2 f3
do
     printf 'Loop: %s %s %s\n' "$f1" "$f2" "$f3"
done <<< "192.168.0.1:2000:1000"
printf 'After: %s %s %s\n' "$f1" "$f2" "$f3"

你做了一个构造,你可以使用在循环中设置的变量,但不能使用 read 设置的变量。 你可以使用

while IFS=: read -r xf1 xf2 xf3
do
     printf 'Loop: %s %s %s\n' "$xf1" "$xf2" "$xf3"
     f1=$xf1
     f2=$xf2
     f3=$xf3
done <<< "192.168.0.1:2000:1000"
printf 'After: %s %s %s\n' "$f1" "$f2" "$f3"

我猜你不想使用这个,所以请阅读循环内的行:

while read -r line
do
     IFS=: read -r f1 f2 f3 <<< "${line}"
     printf 'Loop: %s %s %s\n' "$f1" "$f2" "$f3"
done <<< "192.168.0.1:2000:1000"
printf 'After: %s %s %s\n' "$f1" "$f2" "$f3"

【讨论】:

    【解决方案3】:

    它已知的 bash 行为。在这里阅读,为什么以及如何避免:http://mywiki.wooledge.org/BashPitfalls#grep_foo_bar_.7C_while_read_-http://mywiki.wooledge.org/BashFAQ/024

    【讨论】:

    • 这些链接适用于与问题不同的场景。这些描述了cmd | while read … 的东西;此处不适用。
    • 我保持纠正,没有仔细看。结果看起来相似,但根本原因不同。
    猜你喜欢
    • 2014-02-15
    • 1970-01-01
    • 2013-06-24
    • 2016-12-10
    • 2013-02-05
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多