Ответ больше имеет отношение к истории условий, чем их фактическое значение.
В первые годы терминалы были устройствами, как DEC VT101, у меня есть нахождение в моем гараже.:-)
Эмуляторы терминала прибыли позже. Я не знаю то, что было на первом месте, но теперь у нас есть несколько различных видов эмуляторов терминала.
minicom
, и т.д.)x3270
и tn5250
придите на ум),xterm
, rxvt
, и т.д.)Я предполагаю, что терминал, сидящий рядом с компьютером, упоминался как консоль в первые годы, но позже который прибыл для значения клавиатуры и монитора, подключенного к компьютеру. На Linux, по крайней мере, исторически только была одна консоль (Ваша видеокарта и монитор, объединенный с приложенными клавиатурами и мышами), но у нас были виртуальные консоли, которые позволяют нам переключаться от одной "консоли" до другого на одной консоли. (/dev/console
и /dev/tty0
укажите на одну основную консоль.)
vi $(locate php.ini)
Примечание: это будет иметь проблемы, если Ваши пути к файлам будут иметь пробелы, но это функционально эквивалентно Вашей команде.
Эта следующая версия правильно обработает пробелы, но немного более сложна (новые строки в именах файлов все еще повредят ее хотя),
(IFS=$'\n'; vi $(locate php.ini))
Объяснение:
То, что происходит, - то, что программы наследовали свои дескрипторы файлов от процесса, который породил их. xargs
имеет его STDIN, подключенный к STDOUT locate
, так vi
не имеет никакой подсказки что исходный STDIN действительно в.
Этот вопрос ранее задали на форуме Суперпользователя.
Заключение в кавычки из ответа @grawity по тому вопросу:
При вызове программы через xargs stdin программы (стандартный вход) указывает на/dev/null. (Так как xargs не знает исходный stdin, он делает следующую лучшую вещь.)
Vim ожидает, что его stdin совпадет с его терминалом управления и выполняет различный связанный с терминалом ioctl's на stdin непосредственно. При выполнении на/dev/null (или любой non-tty дескриптор файла), те ioctls бессмысленны и возвращают ENOTTY, который тихо проигнорирован.
Это упоминается в страницах руководства для xarg. От OSX/BSD:
- o Вновь открыли stdin как/dev/tty в дочернем процессе прежде, чем выполнить команду. Это полезно, если Вы хотите, чтобы xargs запустил интерактивное приложение.
Следовательно, на OSX, Вы могли использовать следующую команду:
find . -name "php.ini" | xargs -o vim
В то время как, нет никакого прямого переключателя на версии GNU, эта команда будет работать. (Удостоверьтесь, что включали dummy
строка, иначе это отбросит первый файл.)
find . -name "php.ini" | xargs bash -c '</dev/tty vim "$@"' dummy
Вышеупомянутыми решениями является любезность Jaime McGuigan на SuperUser. Добавление их здесь для любых будущих посетителей, ищущих сайт эту ошибку.
xargs sh -c 'emacs "$@" < /dev/tty' emacs
поскольку то, чего они требуют, является более гибкой и портативной альтернативой (хотя это довольно забавно для GNU, чтобы быть, предпочитают мобильность функциям :).
– cas
01.08.2012, 01:22
Быстрый способ сделать это состоит в том, чтобы использовать обратные галочки (иначе серьезные диакритические знаки) для выполнения команды до другого выполнения команды.
Например.
vi `find / -type f -name 'php.ini'`
Команда, содержавшая в обратных галочках, выполнится сначала. Вывод содержавшей команды затем выполняется командой, указанной перед обратными галочками.
Например, в строке выше, find / -type f -name 'php.ini'
команда выполнится сначала, отправить вывод, и затем vi
будет выполняться на том выводе.
$(find ...)
вместо этого.
– cas
01.08.2012, 01:24
vi
использование этого метода. Довольно возможно, что это могло повредиться на новых строках или пробелах, в зависимости от как vi
читает и выполняет вывод.
– tacotuesday
08.08.2012, 09:07
Отредактировать несколько php.ini в том же редакторе?
Попытка: vim -o $(locate php.ini)
Эта ошибка возникает, когда вызывается vim и он подключен к выходу предыдущего конвейера, а не к терминалу и получает другой неожиданный ввод (например, NUL).
то же самое происходит, когда вы запускаете: vim dev / null
, поэтому в этом случае помогает команда reset
. Это хорошо объясняется грубостью суперпользователя .
В Unix / OSX вы можете использовать xargs
с параметром -o
, например:
locate php.ini | xargs -o vim
-o
Повторно открыть stdin как / dev / tty в дочернем процессе перед выполнение команды. Это полезно, если вы хотите, чтобы xargs запускал интерактивное приложение.
В Linux попробуйте следующее обходное решение:
locate php.ini | xargs -J% sh -c 'vim < /dev/tty $@'
В качестве альтернативы используйте GNU parallel
вместо xargs
, чтобы принудительно выделить tty, например:
locate php.ini | parallel -X --tty vi
Примечание: parallel
в Unix / OSX не будет работать, так как имеет другие параметры и не поддерживает tty.
Многие другие популярные команды также обеспечивают выделение псевдо-tty (например, -t
в ssh
), поэтому обратитесь за помощью.
В качестве альтернативы используйте find
, чтобы передать имена файлов для редактирования, поэтому не нужно xargs
, просто используйте -exec
, например:
find /etc -name php.ini -exec vim {} +
Взлом @Patrick IFS
необходим только для тупых оболочек, таких как bash
и zsh
. fish
по умолчанию разбивает строку на новые строки.
$ vim (locate php.ini)
И да поможет нам всем Бог, если хотя бы у одного из нас действительно есть файл с новой строкой в имени. После 17 лет использования Linux я ни разу его не видел. Я бы побеспокоился о поддержке имен файлов с символами новой строки только для сценариев, которые должны работать несмотря ни на что, но такие сценарии, вероятно, не запускают vim в интерактивном режиме.
С GNU findutils
и оболочкой с поддержкой замены процесса (ksh, zsh, bash )вы можете сделать:
xargs -r0a <(locate -0 php.ini) vi
Идея заключалась в том, чтобы передать список файлов через -a filename
, а не стандартный ввод. Использование -0
гарантирует, что он работает независимо от того, какие символы или не -символы могут содержаться в именах файлов.
С помощью zsh
можно сделать:
vi ${(0)"$(locate -0 php.ini)"}
(где 0
— флаг расширения параметра для разделения на NUL ).
Однако обратите внимание, что, в отличие от xargs -r
, по-прежнему выполняется vi
без аргументов, если файл не найден.
xargs
поскольку это не могло быть сделано непосредственно с оболочкой (илиfind
). Однако я могу думать о случаях, где это было бы лучшее решение. Так, пока Вы понимаете чтоxargs
делает, как это разделяет аргументы, как это запускает программу, и т.д., и использует его правильно, я сказал бы, идут для него, обратные галочки :-P – Patrick 01.08.2012, 01:23... | awk '{print $3}' | xargs | sed -e 's/ /+/g' | bc
(для складывания всех значений поля 3). или сsed -e 's/ /|/g'
для построения regexp. и да, как любой инструмент, действительно необходимо знать, как использовать его и каковы его ограничения и протесты. – cas 01.08.2012, 01:29