псевдонимы bash, установленные в то время как цикл не сохраняется - PullRequest
0 голосов
/ 27 мая 2019

Хорошо, я написал сценарий оболочки для чтения файла в формате:

shortcut1 / path / to / directory1
ярлык2 / путь / к / каталогу2

и он должен прочитать файл и создать псевдонимы так, чтобы при вводе shortcut1 cd я попал в сопоставленный каталог. Проблема в том, что любые псевдонимы, установленные в цикле, не сохраняются вне скрипта.

Сначала я попробовал запустить скрипт.

. ./build_shortcuts.sh "~ / .shortcuts"

где файл ~ / .shortcuts содержит

дл ~ / Загрузки
музыка / музыка
dtop ~ / Desktop

Это не сработало. Затем я попытался установить некоторые псевдонимы вне цикла. Например, псевдоним hello = 'world'; alias world = 'hellob'. Я перезапустил сценарий, набрал псевдоним, чтобы получить список псевдонимов, и он включал в себя псевдонимы hello и world, но ни один из них не был установлен в цикле.

Тогда я подумал, что, возможно, цикл не устанавливает их вообще, поэтому я добавил псевдоним в качестве последней команды в сценарии, чтобы он выводил псевдонимы в конце; в этом случае он включал псевдонимы, но они все еще не сохранялись в моем сеансе.

build_shortcuts.sh

script="$(cat $@ | sed -r -e 's/#[A-Za-z0-9 ]*$//' -e '/^\s+/s/^\s+//' -e '/^\s*$/d' -)"
# strip comments, entry level indentation & empty lines (in that order) from filestream

echo "${script}" | while read shortcut; do
    cut=$(echo  "${shortcut}" | awk '{         print $1 }')
    dest=$(echo "${shortcut}" | awk '{ $1=nil; print $0 }')
    dest="${dest:1}" # trim leading whitespace character

    alias "${cut}" &>/dev/null

    if [ $? = 0 ]; then
        echo "Warning: shortcut \"${cut}\" already exists" >&2
        continue # by default, skip overwriting shortcuts
    fi

    echo alias ${cut}="'cd ${dest}'"
    alias "${cut}"="'cd ${dest}'"
done

Я хочу, чтобы псевдонимы, установленные в цикле внутри скрипта, существовали вне скрипта. В настоящее время они не делают.

Я работаю на "GNU bash, версия 5.0.7 (1) -релиз (x86_64-pc-linux-gnu)" на arch linux.

Ответы [ 2 ]

2 голосов
/ 27 мая 2019

С Страница руководства Bash (раздел на Конвейеры ):

Каждая команда в конвейере выполняется как отдельный процесс (т. Е.в подоболочке)

Поскольку цикл выполняется как часть канала, он будет подоболочкой, и команда псевдонима, которую вы выполняете в подоболочке, будет установлена ​​только для этой подоболочки.

Возможным обходным решением будет сохранение псевдонимов в списке, а затем выполнение реальных команд alias во втором цикле, цикле, который не является частью канала или подоболочки.

0 голосов
/ 27 мая 2019

Ваш скрипт может быть немного уменьшен: ему не нужно вызывать так много внешних инструментов.

while read -r cut dest; do
    if alias "${cut}" &>/dev/null; then
        echo "Warning: shortcut \"${cut}\" already exists" >&2
    else        
        echo alias ${cut}="'cd ${dest}'"
        alias "${cut}"="'cd ${dest}'"
    fi
done < <(
    sed -E -e 's/#[A-Za-z0-9 ]*$//' -e '/^\s+/s/^\s+//' -e '/^\s*$/d' "$@"
)

после "done" я перенаправляю ввод из подстановки процесса: это позволяет избежать запуска цикла "while read" в подоболочке.

...