bash: скрипт для определения конкретного псевдонима, вызывающего ошибку - PullRequest
0 голосов
/ 17 апреля 2019

[Arch Linux v5.0.7 с GNU bash 5.0.3]

Некоторые псевдонимы .bashrc, кажется, конфликтуют с bash сценариями оболочки, предоставленными pyenv и pyenv-virtualenvwrapper.
Я обнаружил проблему при запуске сценария, используя set -x и со всеми включенными псевдонимами и, наконец, увидел, что скрипт корректно завершается с кодом выхода, равным 0, только когда псевдонимы отключены с помощью unalias -a. Так что это связано с псевдонимами ... но какой?

Чтобы попытаться автоматизировать это, я написал скрипт оболочки ниже:

  • Вызывает псевдоним по одному за раз, итеративно считывая из полного списка псевдонимов,
  • Он проверяет конфликтующий сценарий оболочки test.sh с этой конфигурацией псевдонимов, оставляющих один, и печатает что-то в случае обнаружения ошибки,
  • отменяет предыдущее сглаживание,
  • Продолжается сглаживание следующего псевдонима.

Но две встроенные alias и unalias не очень хорошо работают в сценарии cac.sh ниже:

#! /usr/bin/bash
[ -e aliases.txt ] && rm -f aliases.txt
alias | sed 's/alias //' | cut -d "=" -f1 > aliases.txt
printf "File aliases.txt created with %d lines.\n" \
        "$(wc -l < <(\cat aliases.txt))"
IFS=" "
n=0
while read -r line || [ -n "$line" ]; do
    n=$((n+1))
    aliasedAs=$( alias "$line" | sed 's/alias //' )
    printf "Line %2d: %s\n" "$n" "$aliasedAs" 
    unalias "$line"
    [ -z $(eval "$*" 1> /dev/null) ] \   # check output to stderr only
         && printf "********** Look up: %s\n" "$line"
    eval "${aliasedAs}"
done < <(tail aliases.txt)  # use tail + proc substitution for testing only

Используйте скрипт так: $ cac.sh test.sh [optional arguments to test.sh] Любой test.sh подойдет. Просто нужно вернуть некоторую непустую строку в stderr.

Первая аномалия в том, что файл aliases.txt пуст, как если бы встроенный alias был недоступен из скрипта. Если я запускаю сценарий с его 3-й строки, используя уже заполненный файл aliases.txt, сценарий завершается с ошибкой во второй строке блока while, опять же, как если бы alias не могло быть вызвано из сценария. Любые предложения приветствуются.

Примечание: Один вкладыш ниже работает в консоли:

$ n=0;while read -r line || [ -n "$line" ]; do n=$((n+1)); printf "alias %d : %s\n" "$n" "$(alias "$line" | sed 's/alias //')"; done < aliases.txt

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Я бы вообще не советовал вообще реализовывать это как внешний скрипт - это имеет гораздо больше смысла как функция, которая может быть оценена непосредственно в вашей интерактивной оболочке (которая, в конце концов, где все потенциально задействованные псевдонимыопределены)если вы передаете, выполняет функцию, вы хотите быть уверены, что эта функция определена внутри кода eval 'd;поскольку псевдонимы являются поведением синтаксического анализатора, они имеют место, когда функции определены , а не когда функции run .

0 голосов
/ 18 апреля 2019

@ Kamil_Cuk, @Benjamin_W и @cdarke указали на тот факт, что неинтерактивная оболочка (как порожденная из скрипта bash) не имеет доступа к псевдонимам.

@ CharlesDuffy указала на вероятное словорасщепление и расширение глобуса приводят к чему-то, что может быть недопустимым синтаксисом теста в исходном блоке [ -z $(eval "$*" 1> /dev/null) ] выше или, что еще хуже, при возможности синтаксического анализа $(eval "$*" 1> /dev/null) как глоба, что приводит к непредсказуемому поведению сценария.Блок исправлен на: [ -z "$(eval "$*" 1> /dev/null)" ].

Создание оболочки, созданной интерактивно cac.sh, с #! /usr/bin/bash -i.сделать две встроенные alias и unalias вернувшими ненулевой результат при вызове, и BASH_ALIASES[@] стал доступен из скрипта.

#! /usr/bin/bash -i
[ -e aliases.txt ] && rm -f aliases.txt
alias | sed 's/alias //' | cut -d "=" -f1 > aliases.txt
printf "File aliases.txt created with %d lines.\n" \
        "$(wc -l < <(\cat aliases.txt))"
IFS=" "

while read -r line || [ -n "$line" ]; do
    aliasedAs=$( alias "$line" | sed 's/alias //' )
    unalias "$line"
    [ -z "$(eval "$*" 2>&1 1>/dev/null)" ] \   # check output to stderr only
         && printf "********** Look up: %s\n" "$line"
    eval "${aliasedAs}"
done < aliases.txt

Предупреждение: тестированиеtest.sh использует встроенный eval. Произвольный код может быть выполнен в вашей системе, если test.sh и необязательные аргументы не получены из надежного источника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...