5

До недавнего времени в моем файле alias sudo='sudo ' был .zshrc . Сегодня я столкнулся с этой ошибкой при попытке сделать sudo mv:

➜  ~  sudo mv nginx.conf.orig nginx.conf.orig2
sudo: nocorrect: command not found

Теперь поглядывая по сторонам, я обнаружил, что это, похоже, связано с некоторыми командами с префиксом nocorrect и что я могу исправить это с помощью alias sudo='nocorrect sudo' .

Однако проблема возникает, когда я пытаюсь установить свой псевдоним alias sudo='nocorrect sudo ' чтобы позволить себе использовать дополнительные псевдонимы. Я также гарантировал, что мой su использовал zsh, как упомянуто здесь.

➜  ~  alias sudo='nocorrect sudo '            
➜  ~  sudo mv nginx.conf.orig nginx.conf.orig2
sudo: nocorrect: command not found
➜  ~  alias sudo='nocorrect sudo'                           
➜  ~  sudo mv nginx.conf.orig nginx.conf.orig2
➜  ~  su
Password: 
michaelarch# ps -p $$
  PID TTY          TIME CMD
25831 pts/1    00:00:00 zsh

У кого-нибудь есть предложения по решению этой проблемы?

РЕДАКТИРОВАТЬ: alias sudo='sudo ' позволяет вам использовать псевдонимы с вашими командами sudo, например, см. Ниже.

➜  ~  alias cat='echo hello'     
➜  ~  echo goodbye > example.txt
➜  ~  cat example.txt           
hello example.txt
➜  ~  sudo cat example.txt 
goodbye
➜  ~  alias sudo='sudo '
➜  ~  sudo cat example.txt
hello example.txt

Для получения дополнительной информации о моей оболочке:

➜  ~  sudo chsh                               
Changing shell for root.
New shell [/usr/bin/zsh]:    
➜  ~  unalias sudo; alias sudo='nocorrect sudo '
➜  ~  echo $SHELL; which sudo                   
/usr/bin/zsh
sudo: aliased to nocorrect sudo 
➜  ~  sudo mv nginx.conf.orig2 nginx.conf.orig  
sudo: nocorrect: command not found
➜  ~  which mv
mv: aliased to nocorrect mv

2 ответа2

6

Поведение воспроизводимо с:

alias sudo='nocorrect sudo '
alias mv='nocorrect mv '

Итак, при выполнении sudo mv foo bar это расширяется до

nocorrect sudo nocorrect mv foo bar

и выдает ошибку, поскольку noc корректно является зарезервированным словом оболочки и не может быть обработано с помощью sudo.

Причина, по которой псевдоним mv расширяется, заключается в том, что вы определяете alias sudo='nocorrect sudo ' с завершающим пробелом, который впоследствии разрешает расширение псевдонима. Без этого пробела этот пример работает, но вы теряете возможность полностью использовать псевдонимы после sudo.

Обходной путь, чтобы иметь расширение псевдонима обычно после sudo, но для предотвращения ошибки с sudo mv экранируйте команду mv при использовании ее с sudo:

sudo \mv foo bar

Это предотвращает расширение псевдонима mv.

5

Хорошо, я копался в этом некоторое время и нашел кое-что в списке рассылки zsh. Кажется, не существует единого решения "серебряной пули", но есть куча разных решений, которые делают разные вещи. Я собираюсь опубликовать то, что я сделал (что-то вроде копа), но также исследую другие подходы и их проблемы. Я лично собираюсь пойти с:

➜  ~  alias sudo='sudo '
➜  ~  alias nsudo='nocorrect sudo'

РЕДАКТИРОВАТЬ:

Я сейчас пойду с

sudo \mv foo bar

для случаев, когда мне нужно это как описано @mpy в альтернативном ответе.

/РЕДАКТИРОВАТЬ

потому что это позволяет мне использовать псевдонимы большую часть времени, и когда они жалуются, потому что они псевдоним псевдоним, я могу использовать nsudo чтобы я случайно не ударил мои файлы.

Лучшие подходы из списков рассылки Zsh. Там, кажется, есть две темы, которые я нашел на этом. Один из 1999 года здесь (вот вопрос, смотрите дальнейшие действия, особенно этот, который решает проблему с noglob . Я не уверен, что это также решает проблему некорректно (означает ли noglob, что программа некорректна? в противном случае я не думаю, что это так, пожалуйста, прокомментируйте)

alias sudo='my_sudo '

function my_sudo {
    while [[ $# > 0 ]]; do
        case "$1" in
        command) shift ; break ;;
        nocorrect|noglob) shift ;;
        *) break ;;
        esac
    done
    if [[ $# = 0 ]]; then
        command sudo zsh
    else
        noglob command sudo $@
    fi
}

Что удовлетворяет обоим моим требованиям из моего вопроса:

➜  ~  alias cat='echo hello'     
➜  ~  echo goodbye > example.txt
➜  ~  sudo cat
hello
➜  ~  sudo mv example.txt2 example.txt

Также кажется, что это снова появилось в 2008 году в списке рассылки с таким решением:

alias sudo='noglob do_sudo '
function do_sudo
{
    integer glob=1
    local -a run
    run=( command sudo )
    if [[ $# -gt 1 && $1 = -u ]]; then
        run+=($1 $2)
        shift ; shift
    fi
    (($# == 0)) && 1=/bin/zsh
    while (($#)); do
        case "$1" in
        command|exec|-) shift; break ;;
        nocorrect) shift ;;
        noglob) glob=0; shift ;;
        *) break ;;
        esac
    done
    if ((glob)); then
        PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $~==*
    else
        PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $==*
    fi
}

Который, кажется, делает многое, что я по общему признанию не полностью понимаю. Это, кажется, игнорирует автозамену (как указано автором).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .