В Emacs-lisp, как правильно использовать call-process для команды ls? - PullRequest
13 голосов
/ 01 февраля 2011

Я хочу выполнить следующую команду оболочки в emacs-lisp:

ls -t ~/org *.txt | head -5

Моя попытка сделать следующее:

(call-process "ls" nil t nil "-t" "~/org" "*.txt" "| head -5")

Результаты в

ls: ~/org: No such file or directory
ls: *.txt: No such file or directory
ls: |head -5: No such file or directory

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

18 голосов
/ 01 февраля 2011

Проблема в том, что токены, такие как ~, * и |, не обрабатываются / не расширяются программой ls.Поскольку токены не обрабатываются, ls ищет файл или каталог, буквально называемый ~/org, файл или каталог, буквально называемый *.txt, и файл или каталог, буквально называемый | head -5.Таким образом, вы получили сообщение об ошибке «Нет такого файла или каталога».

Эти токены обрабатываются / расширяются оболочкой (например, Bourne shell / bin / sh или Bash / bin / bash). Технически, интерпретациятокены могут быть специфичными для оболочки, но большинство оболочек интерпретируют, по крайней мере, некоторые из одинаковых стандартных токенов одинаково, например, | означает соединение программ друг с другом сквозным образом почти со всеми оболочками. В качестве контрпримера, оболочка Борна (/bin / sh) не выполняет расширение ~ tilde / home-directory.

Если вы хотите получить расширения, вы должны заставить свою вызывающую программу выполнить само расширение как оболочку (тяжелая работа) или выполните команду ls в оболочке (гораздо проще):

/bin/bash -c "ls -t ~/org *.txt | head -5"

, поэтому

(call-process "/bin/bash" nil t nil "-c" "ls -t ~/org *.txt | head -5")

Edit: Уточнены некоторые проблемы, например, упомянуто, что/bin/sh не делает ~ расширение.

12 голосов
/ 01 февраля 2011

В зависимости от вашего варианта использования, если вы захотите выполнять команды оболочки и часто будете делать вывод доступным в новом буфере, вы также можете использовать функцию shell-command.В вашем примере это выглядело бы примерно так:

(shell-command "ls -t ~/org *.txt | head -5")

Однако для вставки этого в текущий буфер потребуется вручную установить current-prefix-arg с помощью чего-то вроде (universal-argument), чтонемного взломать.С другой стороны, если вы просто хотите получить результат где-нибудь, вы можете получить и обработать его, shell-command будет работать так же, как и все остальное.

...