Я хочу создать локальные псевдонимы, пока работаю в определенных каталогах. Например, я хотел бы иметь следующее в файле с именемlocal_alias
alias foo='bar'
Я хотел написать скрипт очистки, чтобы удалить эти псевдонимы после того, как я закончу работу. Что-то вроде:
egrep "alias [[:alnum:]]+" local_alias -o|while read i; do
un$i
done
Если я изменю среднюю строку на echo un$i
, вывод будет выглядеть как правильно отформатированная unalias
команда: unalias foo
. Но в написанном виде я получаю unalias: foo: not found
.
Если я попробую процитировать среднюю строку: "un$i"
, то вместо этого я получу unalias foo: command not found
.
Что я делаю не так?
решение1
Псевдонимы специфичны для оболочки, поэтому, когда вы запускаете свой скрипт следующим образом:
#!/bin/bash
...
unalias ....
...
Он работает как дочерняя оболочка, которая обычно не имеет тех же псевдонимов. Усугубляя проблему, вы также имеете дело с другой проблемой. Как только скрипт завершается, дочерняя оболочка, чьи псевдонимы были удалены, исчезает, возвращая вас к родительской оболочке, которая все еще имеет свои псевдонимы нетронутыми.
Насколько мне известно, нет способа изменить псевдонимы вашей текущей оболочки таким образом.
Так как же это сделать?
Для выполнения этого действия можно создать псевдоним или функцию в рамках текущей оболочки.
Пример
решение псевдонима
$ alias unalias_local='egrep "alias [[:alnum:]]+" local_alias -o|while read i; do un$i; done'
функциональное решение
$ function unalias_local { egrep "alias [[:alnum:]]+" local_alias -o | \
while read i; do un$i; done; }
Проблемы с вышеперечисленным
Автор OP предоставил эти решения для этого ответа, которые, как он заявил, будут работать в его сценарии. Но в общем случае вы не можете изменить псевдонимы в цепочке команд, переданных по конвейеру, как эта, потому что каждый конвейер вызывает подоболочку, которая не сможет коснуться оболочки родителя. Так что мы вернулись к той же проблеме, что и ранее со скриптом.
Чтобы обойти это ограничение, можно вместо этого указать список псевдонимов в качестве аргументов команды.
Пример
$ alias ali1="cmd1"
$ alias ali2="cmd2"
Подтвердите псевдонимы в нашей оболочке:
$ alias | grep -E "ali[12]"
alias ali1='cmd1'
alias ali2='cmd2'
Содержание local_alias
:
$ cat local_alias
alias ali1="cmd1"
alias ali2="cmd2"
Эта команда проанализирует имена псевдонимов из файла local_alias
:
$ grep -oP "(?<=alias )([[:alnum:]]+)" local_alias
ali1
ali2
Мы можем использовать его для unalias
этих псевдонимов следующим образом:
$ unalias $(grep -oP "(?<=alias )([[:alnum:]]+)" local_alias)
$
Теперь, когда мы убедились, что их больше нет:
$ alias | grep -E "ali[12]"
$
решение2
Похоже, вы запускаете этот код в отдельном скрипте. Это не сработает: вам нужно изменить конфигурацию запущенной оболочки, а сделать это из другого процесса вы не сможете. Этот код очистки должен быть в функции, определенной в вашем .bashrc
.
Вторая проблема заключается в том, что конвейер также создает подпроцесс (подоболочку). Поэтому, если вы запустите этот код внутри интерактивной оболочки, команда unalias
удалит псевдоним — но только в подоболочке. Вам нужен другой подход, который не запускает команду unalias
в подоболочке.
Есть несколько решений, но самым простым будет создать список псевдонимов, а затем выполнить команду unalias
один раз. Имена псевдонимов не могут содержать специальные символы, поэтому разбиение слов в списке псевдонимов будет вполне достаточно для генерации аргументов для unalias
.
unalias $(egrep -o "alias [[:alnum:]]+" local_alias)