Bash在“ do <{$ 1}”上返回模糊的重定向错误

时间:2018-10-29 23:41:44

标签: bash shell

我目前正在阅读一本编程书,偶然发现了这个示例

#!/bin/bash
# read file and create INSERT statements for MySQL
#
outfile='members.sql'
IFS=','
while read lname fname address city state zip
do
    cat >> $outfile << EOF
    INSERT INTO members (lname,fname,address,city,state,zip) 
    VALUES ('$lname', '$fname', '$address', '$city', '$state', '$zip');
EOF
done < ${1}

在同一目录中包含一个members.csv文件

Monster,Cookie,123 Pastry Ln,Detroit,MI,66666

重击返回

./test23.sh: line 11: ${1}: ambiguous redirect

运行为

./test23.sh < members.csv

该文件中的所有内容都一目了然地匹配我编程书籍中〜2015年的内容。我尝试了{}()$空格的许多不同组合,没有空格,但总是最终得到一个模棱两可的重定向错误。这都是通过emacs shell在/ bin / bash上运行的,但是我退出了emacs并通过父级LXTerminal尝试了它,但它仍然给我同样的错误。我已经尝试了具有和没有读写和执行权限的members.csv文件,并确保对test23.sh的权限是正确的,我迷路了。

EDIT1: 好的,伙计们,事实证明跨外壳和bash版本使用此脚本的正确方法是

done >"$1"

修复语法后,我将其运行为

./test23.sh members.csv

在没有任何其他重定向的情况下,输出到members.sql是

    INSERT INTO members (lname,fname,address,city,state,zip) VALUES 
('Blum', 'Richard', '123 Main St.', 'Chicago', 'IL', '60601');
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES 
('Blum', 'Barbara', '123 Main St.', 'Chicago', 'IL', '60601');
    INSERT INTO members (lname,fname,address,city,state,zip) VALUES 
('Bresnahan', 'Christine', '456 Oak Ave.', 'Columbus', 'OH', '43201');

2 个答案:

答案 0 :(得分:3)

重定向是“模糊的”,因为您的$1是空的:您根本没有向脚本传递参数,因为<members.csv不是脚本的参数-这是对脚本的指令关于如何在完全启动脚本之前配置stdin 的外壳程序。

您应该执行这两项操作之一,但不能同时执行

  • 通过运行members.csv来传递./test23.sh members.csv作为参数,并将重定向的引号固定为<"$1",以便所有shell版本都可以正确地对其进行解析。
  • 通过运行members.csv在stdin上连接./test23.sh <members.csv,但是请勿在脚本内使用重定向(因为重定向已由父shell完成在完全启动脚本之前)。

答案 1 :(得分:1)

您需要在调用中摆脱<。试试这个:

./test23.sh  members.csv

为我工作。

编辑:感谢查尔斯·达菲

为了实现跨版本的可操作性,最好还在bash脚本中的位置参数访问周围添加引号,以便使底线可以变为:

done < "${1}"

done < "$1"