Ответ 1
Это связано с тем, что вы используете бесполезную команду cat
с каналом, в результате чего создается подоболочка. Попробуйте без cat
:
while read filename ; do
N=$((N+1))
....
done < file
Я новичок в bash сценариях. Кажется, я не могу получить правильное значение моих переменных подсчета для отображения в конце цикла while
в моем bash script.
Фон: у меня довольно простая задача: я хочу передать текстовый файл, содержащий список путей к файлу, в bash script, проверить его существование и подсчитать количество существующие/отсутствующие файлы. Я получил большую часть работы script, за исключением счетной части.
N=0
correct=0
incorrect=0
cat $1 | while read filename ; do
N=$((N+1))
echo "$N"
if ! [ -f $filename ]; then
incorrect=$((incorrect+1))
else
correct=$((correct+1))
fi
done
echo "# of Correct Paths: $correct"
echo "# of Incorrect Paths: $incorrect"
echo "Total # of Files: $N"
Если у меня есть список из 5 файлов, из которых 4, я ожидаю получить следующий вывод (обратите внимание на команду echo
в цикле while
):
1
2
3
4
5
# of Correct Paths: 4
# of Incorrect Paths: 1
Total # of Files: 5
Вместо этого я получаю:
1
2
3
4
5
# of Correct Paths: 0
# of Incorrect Paths: 0
Total # of Files: 0
Что случилось со значениями этих переменных? У Google было много предложений сомнительного качества, и я думаю, что я мог бы заставить его работать с небольшим количеством поисков, но краткое объяснение того, что я делаю неправильно, было бы очень полезно.
Это связано с тем, что вы используете бесполезную команду cat
с каналом, в результате чего создается подоболочка. Попробуйте без cat
:
while read filename ; do
N=$((N+1))
....
done < file
В качестве альтернативы, если вы хотите сохранить cat
по какой-либо причине, вы можете исправить свой script просто добавив эту строку перед инструкцией cat
:
shopt -s lastpipe
В общем, иногда вы хотите передать вывод команды. Вот пример, который использует замещение процесса, чтобы вставлять файлы JavaScript, которые должны быть зафиксированы с помощью Git, и подсчитывает количество неудачных файлов:
# [email protected] glob
git-staged-files() {
git diff --cached -C -C -z --name-only --relative --diff-filter=ACMRTUXB "[email protected]"
}
# [email protected] name
map() { IFS= read -rd $'\0' "[email protected]"; }
declare -i errs=0
while map file; do
echo "Checking $file..."
git show ":$file"|
eslint --stdin --stdin-filename "$file" || ((++errs))
done < <(git-staged-files \*.js)
((errs)) && echo -en "\e[31m$errs files with errors.\e[00m " >&2 || :