Вопрос или проблема
Это немного смешная ситуация, по крайней мере для меня. У меня есть файл, с которым я запускаю команды awk и cut в цикле, используя команду head. Команда выглядит так:
head -n X all.du.K.txt | while read line ; do NON_APP=$(echo ${line} | awk '{print $1}' | cut -d"," -f2) ; APP=$(echo ${line} | awk '{print $2}' | cut -d"," -f2) ; PATH=$(echo ${line} | awk '{print $3}') ; echo ${PATH},${NON_APP},${APP} ; done >> final.csv
Если X равно 1, все работает, но если X равно 2 или любому другому числу, я получаю следующую ошибку:
head -n 2 all.du.K.txt | while read line ; do NON_APP=$(echo ${line} | awk ‘{print $1}’ | cut -d”,” -f2) ; APP=$(echo ${line} | awk ‘{print $2}’ | cut -d”,” -f2) ; PATH=$(echo ${line} | awk ‘{print $3}’) ; echo ${PATH},${NON_APP},${APP} ; done >> final.csv
Команда ‘cut’ доступна в следующих местах
- /bin/cut
- /usr/bin/cut
Команду не удалось найти, потому что ‘/bin:/usr/bin’ не включен в переменную окружения PATH.
cut: команда не найдена
Команда ‘awk’ доступна в следующих местах- /bin/awk
- /usr/bin/awk
Команду не удалось найти, потому что ‘/bin:/usr/bin’ не включен в переменную окружения PATH.
awk: команда не найдена
Команда ‘awk’ доступна в следующих местах- /bin/awk
- /usr/bin/awk
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
awk: команда не найдена
Команда ‘cut’ доступна в следующих местах- /bin/cut
- /usr/bin/cut
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
cut: команда не найдена
Команда ‘awk’ доступна в следующих местах- /bin/awk
- /usr/bin/awk
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
awk: команда не найдена
Моя переменная окружения $PATH выглядит следующим образом:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Если запустить вышеупомянутый цикл с включенной set -x, я получаю следующий вывод, просто для вашего сведения:
- head -n 2 all.du.K.txt
- read line
++ echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,5375K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,17086K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c
++ awk ‘{print $1}’
++ cut -d, -f2- NON_APP=5375K
++ echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,5375K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,17086K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c
++ awk ‘{print $2}’
++ cut -d, -f2- APP=17086K
++ echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,5375K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,17086K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c
++ awk ‘{print $3}’- PATH=/var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c
- echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,5375K,17086K
- read line
++ echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,145K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,191K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4
++ awk ‘{print $1}’
++ ‘[‘ -x /usr/lib/command-not-found ‘]’
++ cut -d, -f2
++ /usr/lib/command-not-found — awk
++ ‘[‘ -x /usr/lib/command-not-found ‘]’
++ /usr/lib/command-not-found — cut
Команда ‘cut’ доступна в следующих местах
- /bin/cut
- /usr/bin/cut
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
cut: команда не найдена
Команда ‘awk’ доступна в следующих местах- /bin/awk
- /usr/bin/awk
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
awk: команда не найдена
++ return 127
++ return 127
- NON_APP=
++ echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,145K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,191K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4
++ awk ‘{print $2}’
++ ‘[‘ -x /usr/lib/command-not-found ‘]’
++ /usr/lib/command-not-found — awk
++ cut -d, -f2
++ ‘[‘ -x /usr/lib/command-not-found ‘]’
++ /usr/lib/command-not-found — cut
Команда ‘cut’ доступна в следующих местах
- /bin/cut
- /usr/bin/cut
Команду не удалось найти, потому что ‘/bin:/usr/bin’ не включен в переменную окружения PATH.
cut: команда не найдена
Команда ‘awk’ доступна в следующих местах- /bin/awk
- /usr/bin/awk
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
awk: команда не найдена
++ return 127
++ return 127
- APP=
++ echo /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,145K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,191K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4
++ awk ‘{print $3}’
++ ‘[‘ -x /usr/lib/command-not-found ‘]’
++ /usr/lib/command-not-found — awk
Команда ‘awk’ доступна в следующих местах
- /bin/awk
- /usr/bin/awk
Команду не удалось найти, потому что ‘/usr/bin:/bin’ не включен в переменную окружения PATH.
awk: команда не найдена
++ return 127
- PATH=
- echo ,,
- read line
Пример из моего входного файла:
/var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,5375K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c,17086K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/e7/e0e72896f2d07d134de6efb2d6541bed7e297e17f010f67f30247abc56d92c6c
/var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,145K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4,191K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/38/e03865e0382175da3126eb126534c2d3c9b4cf69483fa8a167d05c070360edc4
/var/opt/gitlab/gitlab-rails/shared/artifacts/e0/f2/e0f23d7875aff9c6b4ef20f27e7d38c4e312811ae627319267f566a4dc244636,168K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/f2/e0f23d7875aff9c6b4ef20f27e7d38c4e312811ae627319267f566a4dc244636,555K /var/opt/gitlab/gitlab-rails/shared/artifacts/e0/f2/e0f23d7875aff9c6b4ef20f27e7d38c4e312811ae627319267f566a4dc244636
Есть идеи, что здесь происходит? Версия Bash: “GNU bash, версия 5.0.17(1)-release (x86_64-pc-linux-gnu)”
Вы перезаписываете $PATH в цикле:
PATH=$(echo ${line} | awk '{print $3}')
Вам следует использовать другое имя для этой переменной, например APP_PATH
.
Ответ или решение
Ваша ситуация действительно имеет свои нюансы, и, скорее всего, проблема заключается в перезаписи переменной окружения PATH
в вашем цикле. Давайте рассмотрим эту ситуацию более подробно.
Проблема
Вы используете команду head
для извлечения первых X
строк из файла и затем обрабатываете каждую строку в цикле while
. Однако во время обработки строки вы присваиваете значение переменной PATH
следующим образом:
PATH=$(echo ${line} | awk '{print $3}')
В результате, с каждой итерацией цикла, когда значению PATH
присваивается новое значение (которое, и скорее всего, является частью строки), вы фактически перезаписываете значение системной переменной окружения PATH
, отвечающей за указание местоположения исполняемых файлов. Это объясняет, почему вы видите ошибки о том, что команды awk
и cut
не найдены.
Решение
Чтобы избежать этой проблемы, вы можете использовать другое имя для вашей переменной, например, APP_PATH
, вместо того чтобы использовать PATH
. Вот как это можно сделать:
head -n X all.du.K.txt | while read line; do
NON_APP=$(echo ${line} | awk '{print $1}' | cut -d"," -f2)
APP=$(echo ${line} | awk '{print $2}' | cut -d"," -f2)
APP_PATH=$(echo ${line} | awk '{print $3}')
echo ${APP_PATH},${NON_APP},${APP} >> final.csv
done
Теперь значение переменной APP_PATH
будет храниться отдельно от системной переменной PATH
, предотвращая любые потенциальные конфликты.
Дополнительные советы
-
Улучшение производительности: Использование однократного вызова
awk
вместо нескольких вызовов приведет к улучшению производительности. Например, извлечение всех трех значений сразу:head -n X all.du.K.txt | while read line; do IFS=',' read -r first second third <<< $(echo ${line} | awk '{print $1","$2","$3}') NON_APP=$(echo ${first} | cut -d"," -f2) APP=$(echo ${second} | cut -d"," -f2) APP_PATH=${third} echo ${APP_PATH},${NON_APP},${APP} >> final.csv done
-
Проверка наличия ошибок: Поскольку вы обрабатываете данные из файла, полезно добавить проверку на наличие ошибок для команды
read
, чтобы убедиться, что строки действительно читаются правильно и не приводят к ошибкам. -
Отладка кода: Используйте
set -x
в начале вашего скрипта, чтобы отслеживать выполнение команд и находить возможные ошибки на ранних этапах.
Заключение
Перезапись переменной окружения PATH
– это частая ошибка, которая может привести к неожиданному поведению в ваших скриптах. Использование уникальных имен для переменных помогает избежать подобных ситуаций и поддерживать чистоту кода. Выполнив предложенные изменения, вы сможете избежать ошибок и сделать ваш скрипт более эффективным.
Если у вас остались вопросы или нужны дополнительные разъяснения, не стесняйтесь обращаться!