Автоматически обнаружьте, когда я ввел “vi”, но имел в виду “CD”?

Если бы Вы перенаправляете stdout для остальной части сценария, то это включало бы команду "кошки", таким образом, Вы не будете видеть ее вывода, $file мог заполниться неограниченно долго рекурсивными копиями себя (и будете, если это не было бы столь маленьким, чтобы позволить cat посмотрите конец его прежде, чем начать писать в него).

Для перенаправления stdout с этого времени Вы просто делаете:

exec > "$file"

Но здесь возможно, Вы хотите:

#! /bin/bash -
{
  echo spo 
  echo car
} > "$file"

cat < "$file"

Можно также сделать вещи как:

exec 3>&1 # save stdout as fd 3
exec > "$file"
echo spo
echo car
exec >&3 3>&- # restore stdout and close fd 3
cat < "$file"

(и между прочим, вышеупомянутое - то, что современные оболочки делают внутренне при перенаправлении составной команды как { some; code; } > ... (хотя они используют fd выше 10 и устанавливают флаг O_CLOEXEC на нем так, чтобы выполняемые команды не видели его), в то время как Оболочка Bourne разветвила бы подоболочку в этом случае),

Также обратите внимание, что в коде выше, Вы не должны восстанавливать stdout для остальной части сценария, можно сделать это для cat команда только:

cat < "$file" >&3 3>&-

( 3>&- (заключительный fd 3), не необходимо как cat не использует его fd 3 так или иначе, но хорошая практика в общем случае, и строго говоря, мы должны были бы добавить его к каждой команде для эмуляции поведения O_CLOEXEC оболочки).

21
18.02.2019, 22:51
4 ответа

Учитывая, что Вы звоните vi с каталогом как последний аргумент:

vi() {
    if [[ -d ${!#} ]]; then
        cd "$@"
    else 
        command vi "$@"
    fi
}
38
27.01.2020, 19:43
  • 1
    @Alex я предполагаю это, оба идеально подходит для редких случаев, Вы ввели "vi" неправильно вместо "CD", в то время как одновременно учат Вас всегда вводить "vi" теперь ;) [т.е., я надеюсь, что необходимо не часто использовать другой сервер/машину, где та функция не будет там для сохранения Вас напряжение...] [+1 для того ответа, тем не менее, это - то, на что я хотел ответить также, кроме я просто протестирую на "$ {1}" [и затем CD "$ {1}"] вместо "$ {! #}"...] Согласованный –  Olivier Dulac 16.01.2014, 11:08
  • 2
    @OlivierDulac - столь же опасный искажает rm кому: rm -i, который является значением по умолчанию во многих дистрибутивах. Я обычно думаю, что лучший способ решить проблемы состоит в том, чтобы решить пользователя, а не работать вокруг них. –  Chris Down 16.01.2014, 11:11
  • 3
    @OlivierDulac rm кому: rm -i возможно, сохранил Вас некоторая проблема в прошлом, но мог бы (и вероятно будет) приводить Вас намного больше проблемы в будущем... –  jlliagre 16.01.2014, 13:25
  • 4
    @Alex ну, Вы действительно говорили vi в вопросе... –  Chris Down 20.01.2014, 08:38
  • 5
    @crisron: ${!#} косвенно ссылается на заключительный аргумент, и command только необходимо для предотвращения функциональной рекурсии в этом экземпляре. –  Chris Down 28.01.2014, 04:28

Кроме ответа @ChrisDown, вот другой подход: обходные каталоги

С этим подходом Вы можете:

vi ./*

и это запустит vi на всех файлах в текущем каталоге, даже если это будет содержать subdirs, обходя те subdirs

vi() {
  for arg do
    [ -d "$arg" ] || set -- "$@" "$arg"
    shift
  done
  [ "$#" -gt 0 ] && command vi "$@"
}

Этот просто делает vi на любом аргументе, которые не являются каталогами... Следовательно это не будет учить Вас использовать "vi" для "CD" ;)

И это не назовет vi, если Вы просто сделали: vi somedirectory (т.е., введенный с опечаткой vi вместо CD). Но это не будет CD там автоматически затем, таким образом, Вы все еще будете помнить, что необходимо ввести CD ^^

Я использовал "совместимый" способ изменить списки аргументов, так, чтобы это было портативно на многие платформы.

4
27.01.2020, 19:43
  • 1
    : command something : запускается "что-то" управляют (т.е., первое вхождение "чего-то" найденного использованием $PATH) вместо любого псевдонима, ИЛИ функция назвала "что-то". \something был бы только обходить псевдоним, но был бы все еще функция, если бы это существовало (и здесь, который означал бы, что функция "vi" назовет себя и цикл). –  Olivier Dulac 16.01.2014, 11:55
  • 2
    @ChrisDown редактирования: мы говорим помощь пользователю, который я надеюсь, не попытается взломать себя ^^. И та оценка должна установить новый набор аргументов (набор-...), таким образом, это менее опасно сам по себе –  Olivier Dulac 16.01.2014, 12:01
  • 3
    @StephaneChazelas: спасибо за редактирование! Я пытался записать этому тот путь, но я волновался по поводу цикличного выполнения бесконечно [я доверяю Вам, это не циклично выполнится, хотя!. 'Для аргумента' оценивается, прежде чем внутренняя обработка запускается, и поэтому ее "$" список 'сохранен' и выполнен с помощью итераций и не изменен даже при том, что внутренняя обработка изменяет "$"?] конфетка –  Olivier Dulac 16.01.2014, 12:15

Одно решение состоит в том, чтобы прекратить использовать cd в целом. Поместить shopt -s autocd в Вашем .bashrc или setopt autocd в Вашем .zshrc. Затем для изменения на другой каталог введите имя каталога без любой команды.

Не забывайте вводить vi если Вы хотите отредактировать файл.

Если Вы действительно хотите, чтобы единственная команда или изменилась на каталог или отредактировала файл, можно сделать это функцией:

vi () {
  if [ $# -eq 1 ] && [ -d "$1" ]; then
    cd -- "$1"
  else
    command vi "$@"
  fi
}
1
27.01.2020, 19:43

Используйте функцию псевдонима в Unix. После того как Вы искажаете CD к vi, проблема будет разрешена.

-6
27.01.2020, 19:43
  • 1
    ..., это означало бы, что нельзя использовать vi вручную не переопределяя псевдоним, который кажется очень нежелательным. –  Chris Down 16.01.2014, 11:58
  • 2
    Этот ответ сталкивается как немного trollish. Это действительно отвечает на исходный вопрос, поскольку OP не указывал, что им когда-либо был нужен vi на файле. Ответ, хотя несколько забавный, конечно, не полезен. –  gerrit 16.01.2014, 11:59
  • 3
    @ChrisDown Или это учили бы Вас использовать надлежащее vim вместо этого. –  Kevin 16.01.2014, 21:00
  • 4
    @Kevin не является более "надлежащей", чем vi - во многих системах, vi является всем, что доступно. –  Chris Down 21.01.2014, 05:28
  • 5
    @ChrisDown я утверждал бы, что лучше знать, что ожидать. Если Вы ожидаете использовать функции энергии, использовать vim. Если это не доступно, использовать vi и ожидайте более ограниченный набор функций. –  Kevin 21.01.2014, 05:41

Теги

Похожие вопросы