如何使用shell脚本读取数组中的文件内容?

时间:2014-09-02 08:16:47

标签: linux shell

我有一个shell脚本,它将文件读入数组。它与RHEL完美配合,但是当我在Ubuntu上运行相同的脚本时,我收到了一个错误。这是脚本。

file=/root/monitor.txt
while IFS=',' read -ra line ; do
        echo -e "export MASTER_IP=${line[2]}" >> ~/.bashrc
        source ~/.bashrc
done < $file

上述脚本在RHEL中完美运行。我在Ubuntu上运行时遇到的错误是

read: Illegal option -a

2 个答案:

答案 0 :(得分:4)

read -a是一种bash功能,但在Ubuntu上/bin/sh指向dash,它不支持-a选项。有几种方法可以解决这个问题:

  • 在Ubuntu上,只需在bash下运行脚本,将第一行更改为#!/bin/bash(由Charles Duffy建议)

  • 而不是read -a,只需提供变量列表,例如read f1 f2 f3 f4 f5,然后将字段引用为$f1$f2等。例如,如果您有超过5个字段,则需要添加更多变量,否则$f5将包含该行的其余部分。

  • 使用awk代替read。 Awk非常适合这种字段处理任务:你可以用awk -F, '{print "export MASTER_IP=" $3}' $file >> ~/.bashrc替换while循环,然后在结尾处替换源~/.bashrc

答案 1 :(得分:3)

while IFS=, read -r _ _ ip _; do
  printf 'export MASTER_IP=%s\n' "$ip"
done <"$file" >>"$HOME/.bashrc"

这在某些方面更好:

  • 不需要任何基础;将在Ubuntu上使用/bin/sh
  • 仅为整个循环打开输出文件一次,而不是每次写入新行时都无效地重新打开它。

但是,您可以做得更好 - 提高脚本的安全性 - 如果您将其shebang更改为#!/bin/bash(或/usr/bin/env bash,或者适用于您的平台):

#!/bin/bash
while IFS=, read -r _ _ ip _; do
  printf 'export MASTER_IP=%q\n' "$ip"
done <"$file" >>"$HOME/.bashrc"

因为它使用%q而不是%s,所以它也会转义地址,因此它们不能包含$(rm -rf $HOME)等恶意内容 - 您可能不希望将其注入你的~/.bashrc