Кажется, есть проблема с разделением слов в for f in $files
. Обычно оболочка должна разделять значение $files
на пробелы, как это происходит на Dev.
На Dev f
устанавливается одно из трех слов от $files
в каждом цикле цикла for
, на Prod f
получается полное значение $files
, включая пробелы.
Вы устанавливаете переменную IFS
где-нибудь?
Если проблема не в других частях вашего сценария, вы сможете воспроизвести проблему с помощью уменьшенного сценария:
files="foo bar baz"
for f in $files
do
echo "available files are: $f"
done
Если этот минимальный скрипт не показывает разницы, проблема в других частях вашего скрипта.
Чтобы увидеть, отличается ли значение IFS
в Dev и Prod, вы можете добавить его к минимальному сценарию или к исходному сценарию непосредственно перед циклом for
:
# To see if IFS is different. With the default value (space, tab, newline) the output should be
# 0000000 I F S = # \t \n # \n
# 0000012
echo "IFS=#${IFS}#" | od -c
Если вы видите разницу в значении IFS
, вам нужно выяснить, где IFS
изменяется.
Кстати: обычно вы можете опустить | tr '\n' ' '
после команды grep. Оболочка должна принимать \n
как символ разделения слов при обработке for f in $files
. Если нет, то это, вероятно, связано с источником вашей проблемы.
Редактировать: Существует лучшее решение для обработки данных построчно, см.
https://mywiki.wooledge.org/DontReadLinesWithFor и
https://mywiki.wooledge.org/BashFAQ/001
Вы должны использовать while read
... вместо for
...
Модифицированный скрипт (не проверен)
output_path=s3://output
unziped_dir=s3://2019-01-03
hadoop fs -ls "$output_path"/ | awk '{print $NF}' | grep .gz$ | while IFS= read -r f
do
echo "available files are: $f"
filename=$(hadoop fs -ls "$f" | awk -F '/' '{print $NF}' | head -1)
hdfs dfs -cat "$f" | gzip -d | hdfs dfs -put - "${unziped_dir}/${filename%.*}"
echo "unziped file names: ${filename%.*}"
done