第一个大问题:作为命令自行$($2) $line
执行,然后尝试将其输出(如果有)作为另一个命令运行,并作为其参数。你只是想要。$2
$line
$2 $line
第二个大问题:while read ... done < $(ls $1)
不从文件名列表中读取,它会尝试由 ls 的输出指定的文件的内容——这将根据具体情况以多种方式失败。进程替换 ( while read ... done < <(ls $1)
) 或多或少会做你想要的,但它是一个仅限 bash 的功能(即你必须#!/bin/bash
用,而不是开始脚本#!/bin/sh
)。无论如何,解析 ls是个坏主意,你应该几乎总是只使用 shell glob ( *
) 来代替。
该脚本还存在一些其他潜在问题,文件名中的空格(使用$line
周围没有双引号等)和奇怪的风格怪异(您不需要;
在 shell 中的行尾)。这是我对重写的尝试:
#! /bin/sh
if [ $# -ne 2 ]; then
echo "Usage: $0 <dir> <command to execute>"
exit 1
fi
for file in "$1"/*; do
$2 "$file"
done
echo "All done"
请注意,我没有在$2
. 这允许您指定多字命令(例如./myscript thisDir "cat -v"
,将被解释为运行cat
带有-v
选项的命令,而不是尝试运行名为 的命令"cat -v"
)。将第一个参数之后的所有参数作为命令及其参数实际上会更灵活一些,允许您执行例如./myscript thisDir cat -v
、./myscript thisDir grep -m1 "pattern with spaces"
等:
#! /bin/sh
if [ $# -lt 2 ]; then
echo "Usage: $0 <dir> <command to execute> [command options]"
exit 1
fi
dir="$1"
shift
for file in "$dir"/*; do
"$@" "$file"
done
echo "All done"