Я думаю, что правильный ответ здесь - «не делай так». : -)
Причина, по которой ваш текущий скрипт не работает, может быть в том, что подстановочный знак расширяется вашей интерактивной оболочкой, а не вашим скриптом. Попробуйте выполнить команду с echo
в начале строки, чтобы понять, что на самом деле происходит. Когда getopts
видит второй из сопоставленных файлов в глобусе, он прекращает обработку параметров, поэтому -o
никогда не читается, а $outfile
остается неустановленным. А поскольку вы не заключаете в кавычки свою переменную в rm $outfile
, это как если бы вы запускали rm
без параметров. Проверьте разницу в вашей оболочке между rm
и rm ""
.
Кроме того, что происходит с вашим for
l oop, если в имени файла есть пробел? Так как у вас есть bash, у вас есть массивы. И массивы намного лучше для обработки списков файлов.
Возможно, вместо этого используйте что-то вроде этого:
#!/bin/bash
# initialize an array
files=()
while getopts :d:o: opt; do
case "$opt" in
d)
if [[ ! -d "$OPTARG" ]]; then
printf 'ERROR: not a directory: %s\n' "$OPTARG" >&2
exit 65
fi
# add to the array
files+=( "$OPTARG"/* )
;;
o) outfile="$OPTARG" ;;
*)
printf 'ERROR: unknown option: %s\n' "$opt" >&2
exit 64
;;
esac
done
if ! rm -f "$outfile" && touch "$outfile"; then
printf 'ERROR: cannot create %s\n' "$outfile" >&2
exit 73
fi
for f in "${files[@]}"; do
read -r < "$f"
printf '%s\n' "$REPLY"
done > "$outfile"
Вот некоторые основные моменты изменений ....
- Мы, конечно, используем массивы , Массив
${files[@]}
будет содержать один файл на запись без использования пробелов, поэтому при правильном цитировании вы избежите проблем со специальными символами в именах файлов. показать ошибки и выйти, если мы их увидим. (Выходные значения: sysexits .) - Вместо использования
head
мы используем read
и одно перенаправление на $outfile
. Это позволяет сохранить несколько вилок во внешней программе и несколько вызовов fopen()
в ваш выходной файл.
Обратите внимание, что аргумент -d
должен быть каталогом , а не шарик. И вы можете указать параметры несколько раз. Несколько параметров -d
будут добавлены вместе, но будет использоваться только последний параметр -o
.