Баш двойные скобки [[с sudo

386
Brad Dwyer

У меня есть команда, которая работает при запуске от имени текущего пользователя, но если я добавлю sudoк ней префикс, она выдаст ошибку.

Я пытаюсь удалить файл, если это каталог (но не если это символическая ссылка на каталог). Это прекрасно работает:

brad@ip-10-0-0-1:~$ [[ -d /path/to/my/place && ! -L /path/to/my/place ]] && rm -rf /path/to/my/place 

Но если я пытаюсь использовать sudoэто как суперпользователь, я получаю ошибку, потому что sudoкажется, что [[это команда:

brad@ip-10-0-0-1:~$ sudo [[ -d /path/to/my/place && ! -L /path/to/my/place ]] && rm -rf /path/to/my/place sudo: [[: command not found 

Я должен был добавить двойные скобки, чтобы заставить ! -L /path/to/my/placeбит работать; sudoработал нормально с одинарными скобками, когда я работал

brad@ip-10-0-0-1:~$ sudo [ -d /path/to/my/place ] && rm -rf /path/to/my/place 

Но теперь, когда я пытаюсь убедиться, что это не символическая ссылка, я не могу заставить ее работать sudo. Как я могу либо:

  • Получите синтаксис двойных скобок для работы sudoили
  • Получить синтаксис с одной скобкой, чтобы я мог отменить -Lчасть?
1

1 ответ на вопрос

1
Kamil Maciorowski
$ type -a [ [ is a shell builtin [ is /usr/bin/[ $ type -a [[ [[ is a shell keyword $  

Как вы можете видеть [(помимо встроенной оболочки) это обычная команда, которую sudoможно использовать. [[не является. Вам необходимо bashпредоставить [[:

sudo bash -c '[[ -d /path/to/my/place && ! -L /path/to/my/place ]]' && … 

Поскольку [[это ключевое слово оболочки, синтаксический анализатор распознает его и изменяет поведение &&между [[и ]]. Вы не можете использовать &&внутри, [ … ]потому что [действует как команда и ]фактически является последним аргументом, переданным ей. Наличие &&внутри означает, что есть две команды, что неправильно.

Однако [поддерживает -a, так что это может работать:

sudo [ -d /path/to/my/place -a ! -L /path/to/my/place ] && … 

Вы должны избегать этого, хотя. Из этой статьи :

Двоичный файл -aи -o[…] являются расширениями XSI стандарта POSIX. Все они помечены как устаревшие в POSIX-2008. Они не должны использоваться в новом коде. Одна из практических проблем с [ A = B -a C = D ](или -o) состоит в том, что POSIX не указывает результаты команды testили [с более чем 4 аргументами. Это, вероятно, работает в большинстве оболочек, но вы не можете рассчитывать на это. Если вам нужно писать для POSIX-оболочек, вам следует использовать две testили [команды, разделенные &&оператором.

Так что это должно быть безопаснее, если вы хотите использовать [:

sudo [ -d /path/to/my/place ] && sudo [ ! -L /path/to/my/place ] && … 
Отлично! `sudo bash -c ...` Работал как шарм. Благодарю. Brad Dwyer 6 лет назад 0