题
我碰到了以下问题:我正在写一个Linux bash脚本,并如下:
- 读线从文件
- 带的
\n
字符从底线只读 - 执行命令,该命令在那里
例如:commands.txt
ls
ls -l
ls -ltra
ps as
执行的庆典的文件应该得到第一线,并执行它,但是同时 \n
本,壳只是输出"的命令没有发现:ls"
那个脚本的一部分看起来像这样
read line
if [ -n "$line" ]; then #if not empty line
#myline=`echo -n $line | tr -d '\n'`
#myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`
myline=`echo -n $line | tr -d "\n"`
$myline #execute it
cat $fname | tail -n+2 > $fname.txt
mv $fname.txt $fname
fi
评论你们的事情我试图前要求这样。任何解决方案?我砸我的脑袋对于过去几小时超过这个...
解决方案
我总是喜欢 perl -ne 'chomp and print'
为微调换行。很好,很容易记得.
例如 ls -l | perl -ne 'chomp and print'
然而
我不认为那是你的问题在这里虽然。虽然我不确定我理解你如何通过命令的文件中通过的'改为'在你的外壳脚本。
有一个测试脚本我自己的像这样(test.sh)
read line
if [ -n "$line" ]; then
$line
fi
和一个样本输入文件的样本(测试。命令)
ls
ls -l
ls -ltra
如果我经营这样的 ./test.sh < test.cmds
, 我看到预期的结果,其运行的第一命令'ls'在当前的工作目录。
也许你的输入文件的有额外的不可打印的字吗?
我看起来像这样
od -c test.cmds
0000000 l s \n l s - l \n l s - l t
0000020 r a \n
0000023
从你的意见如下,我怀疑你可能已经回车(" "),在你输入文件,这是不一样的东西作为一个新行。是输入文件最初是在DOS格式?如果是这样,那么你就需要转换的2字节DOS行结束" "这个字节的UNIX一个," "实现预期的结果。
你应该能做到这一通过交换" "for" "在你的任何评论说出线。
其他提示
有人已经写了一个程序执行命令:sh文件
如果你真的只想要执行的第一线的一个文件: head -n 1 file |sh
如果你的问题是车返回: tr -d '\r' <file |sh
我试图这样的:
read line
echo -n $line | od -x
用于输入'xxxx,我获得:
0000000 7878 7878
正如你可以看到,没有 \n
在结束内容的变量。我建议,以运行的剧本的选择 -x
(bash -x script
).这将打印的所有命令,因为他们将被执行。
[编辑]你的问题是,你的编辑commands.txt 在窗户。现在,该文件包含CRLF(0d0a)作为行符它混淆了 read
(及 ls\r
不是一个已知的命令)。使用 dos2unix
或类似的把它变成一个Unix文件。
你也可以试试更换回车用空行,只用来砸内置:
line=$'a line\r'
line="${line//$'\r'/$'\n'}"
#line="${line/%$'\r'/$'\n'}" # replace only at line end
printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s'
你需要eval命令
#!/bin/bash -x
while read cmd
do
if [ "$cmd" ]
then
eval "$cmd"
fi
done
我运行了它作为
./script.sh < 文件。txt
和file.txt 为:
ls ls -l ls -ltra ps as
虽然不是工作 ls
, 我建议具有一个看看 find
's -print0
选项
下脚的工作(至少对我来说):
#!/bin/bash
while read I ; do if [ "$I" ] ; then $I ; fi ; done ;