No tengo una forma elegante de eliminar estos dispositivos que no sea forzar la eliminación del módulo v4l2loopback:
sudo modprobe -r v4l2loopback
Проблема в том, что первые два варианта предназначены только для работы с псевдонимами. Это не специальные операторы перенаправления, которые могут определить, есть ли у вас функция или команда с таким же именем. Все, что они делают, — это предотвращают расширение, что и пытается сделать псевдоним
.alias v='sudo vim'
v x.txt
#automatically expands "v" to "sudo vim" and then does the rest of the command
# v x.txt ==> sudo vim x.txt
Bash просто пытается расширить первое слово команды, используя список известных ему псевдонимов (, который вы можете получить с помощьюalias
). Псевдонимы не принимают аргументов и могут быть разделены только первым словом (пробелом -;vim x.txt
не будет расширяться в sudo vimim x.txt
с использованием псевдонима выше )в команде для правильного расширения.
Однако раскрытие никогда не происходит с объектами в одинарных кавычках.:echo '$USER'
выведет литерал $USER
, а не то, что обозначает переменная. Кроме того, bash расширяет \x
доx
(в основном ). Они не добавляются -специально для того, чтобы избежать псевдонима, они просто часть того, как было написано расширение bash. Таким образом, вы можете использовать эти методы, чтобы позволить псевдониму скрывать команду и по-прежнему иметь доступ к фактической команде.
alias ls='ls -la'
ls foo.txt #will expand into ls -la foo.txt
\ls foo.txt #will expand into ls foo.txt
'ls' foo.txt #same as above
'ls foo.txt' #same as above
Однако они не останавливают функции. Функция не нуждается в расширении для работы, она вызывается по своему имени.
ls () {
echo "not an alias"
}
alias ls='echo "an alias"'
ls foo.txt #will echo "an alias"
\ls foo.txt #will echo "not an alias"
'ls' foo.txt #will echo "not an alias"
command ls foo.txt #will actually run `ls`
Если функция вызывает полный путь к двоичному файлу vim
, вы не получите рекурсивный цикл. Кроме того, использование параметра -H
для sudo устанавливает $HOME.
vim() {
if [ -w "$1" ]; then
command vim "$1"
else
sudo env HOME="$HOME" \vim -u ~/.vimrc "$1"
fi
}
Спасибо. Я не думал об этом, но теперь он есть и у меня в .bashrc
.
ОТРЕДАКТИРОВАНО:обновлены вызовы command vim
и sudo env
вместо sudo -h
. таким образом, нет петли, в которой можно было бы оставаться.
Why do the other options not work as I would expect them to?
Потому что в способе выполнения командной строки есть некоторые особенности.
Основная концепция заключается в том, что первое слово командной строки — это команда, которую оболочка будет искать и пытаться выполнить в следующем порядке:
Командная строка разбита на метасимволы (в основном):
metacharacters
A character that, when unquoted, separates words. One of the following:
| & ; ( ) < > space tab newline
Если первое не заключенное в кавычки слово совпадает со словом псевдонима, оно заменяется определением псевдонима. Чтобы избежать циклов, это выполняется только один раз , если новое первое слово соответствует расширяемому псевдониму. Это позволяет работать без циклов:
$ alias ls='ls -la'
$ ls dir # will expand to `ls -la dir`
Обратите внимание, что :Если последний символ значения псевдонима является пробелом, то следующее командное слово, следующее за псевдонимом, также проверяется на расширение псевдонима.
Если (результирующее )первое слово является расширением (подобно $var
), оно заменяется (и подлежит разбиению на слова IFS (и подстановке подстановки ), если оно не заключено в кавычки):
$ var='echo -e '
$ $var test '\twords' # will expand to `echo -e test words`
test words
Результирующее первое слово после описанных выше расширений (после присвоения необязательных переменных )будет искаться в этом порядке:
$PATH
каталогах)Будет выполнено первое найденное совпадение.
Порядок может быть изменен (для теста):
\test
или любое другое расширение. command test
. builtin test
. /bin/test
. Итак, функция, определенная как:
$ ls(){ ls; }
Будет вызываться в бесконечном цикле. Как и скрипт, который вызывает одно и то же первое слово.Что-то вроде:
#!/bin/bash
$0 "$@"
Повторно -будет выполнять один и тот же сценарий в цикле до тех пор, пока ядро не выйдет из строя (, если используемое ядро имеет ограничение на количество последовательных вызовов сценариев ).
Порядок будет показан при запускеtype -a
:
$ test(){ echo test function; }
$ alias test=test
$ type -a
test is aliased to `test'
test is a function
test ()
{
echo test function
}
test is a shell builtin
test is /usr/bin/test
Функция (, определенная в вопросе ), будет обходить только псевдоним с \vim
, но не функцию. Чтобы обойти псевдоним и функции, используйте команду. Эта функция должна делать то, что вам нужно:
vim() {
if [ -w "$1" ]; then
command vim "$1"
else
sudo HOME="$HOME" bash -c 'command vim "$@"' _ -u ~/.vimrc "$1"
fi
}