Bash не использует PATH, определенный в PATH, если я использую любое другое число в head -n, кроме 1.

Вопрос или проблема

Это немного смешная ситуация, по крайней мере для меня. У меня есть файл, с которым я запускаю команды 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, предотвращая любые потенциальные конфликты.

Дополнительные советы

  1. Улучшение производительности: Использование однократного вызова 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
  2. Проверка наличия ошибок: Поскольку вы обрабатываете данные из файла, полезно добавить проверку на наличие ошибок для команды read, чтобы убедиться, что строки действительно читаются правильно и не приводят к ошибкам.

  3. Отладка кода: Используйте set -x в начале вашего скрипта, чтобы отслеживать выполнение команд и находить возможные ошибки на ранних этапах.

Заключение

Перезапись переменной окружения PATH – это частая ошибка, которая может привести к неожиданному поведению в ваших скриптах. Использование уникальных имен для переменных помогает избежать подобных ситуаций и поддерживать чистоту кода. Выполнив предложенные изменения, вы сможете избежать ошибок и сделать ваш скрипт более эффективным.

Если у вас остались вопросы или нужны дополнительные разъяснения, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...