5

次のbashスクリプトを実行します。これは、.shファイルではなくElisp文字列に格納されてから、シェル出力を変数に格納します。

#!/bin/bash
IFS=: read -ra _dirs_in_path <<< "$PATH"

for _dir in "${_dirs_in_path[@]}"; do
    for _file in "${_dir}"/*; do
        [[ -x ${_file} && -f ${_file} ]] && printf '%s\n' "${_file##*/}"
    done
done

shell-command複数の文字列で構成されるbashスクリプトを実行できませんでした。EmacsとLongShellコマンドも、bash構文ではなくコマンドを必要とするためcompile、役に立ちませんでした。comint-run

Elispから複雑なbashスクリプトを実行するにはどうすればよいですか?

4

3 に答える 3

6

複数行のコマンドはbash -c、シェルのメタ文字を含む可能性のある他のシェル引数と同じように引用符で囲む場合の引数として指定できます。例:

(setq my-command
      (concat "IFS=: read -ra dirs <<<\"$PATH\"\n"
              "for dir in ${dirs[@]}; do\n"
              " echo got dir \"$dir\"\n"
              "done\n"))

(shell-command (format "bash -c %s" (shell-quote-argument my-command)))
于 2012-07-26T15:38:25.947 に答える
2

これはおそらくあなたが望むことをするでしょう。味に修飾子を追加します:)

(defun example-multiline-shell-command ()
  (interactive)
  (with-temp-buffer
    (insert "#!/bin/bash
IFS=: read -ra _dirs_in_path <<< \"$PATH\"

for _dir in \"${_dirs_in_path[@]}\"; do
    for _file in \"${_dir}\"/*; do
        [[ -x ${_file} && -f ${_file} ]] && printf '%s\n' \"${_file##*/}\"
    done
done")
    (write-region (point-min) (point-max) "~/temp.sh")
    (shell-command "source ~/temp.sh" (current-buffer))
    (buffer-string)))

編集"${_dirs_in_path[@]}"ああ、そしてファイルに名前の区切り文字として扱われる可能性のあるスペースや他の文字が含まれていると、FYIは悪くなります。

于 2012-07-26T09:59:04.697 に答える
0

shell-command実際にはマルチストリングbash構文で動作します。私の問題は、shell-commandPATHを含むbash環境変数を知らないということでした。私がしたこと:スクリプト内のすべて"を置き換え\"て、それをelisp文字列に入れてから、いくつかのディレクトリをPATHに割り当てました。*Shell Command Output*これは、システム内のすべての実行可能ファイルをバッファに正常に出力するコードです。

(let ((path "PATH='/usr/local/bin:/usr/bin:/bin'")
      (command "IFS=: read -ra _dirs_in_path <<< \"$PATH\"

for _dir in \"${_dirs_in_path[@]}\"; do
    for _file in \"${_dir}\"/*; do
        [[ -x ${_file} && -f ${_file} ]] && printf '%s\n' \"${_file##*/}\"
    done
done"))
  (shell-command (concat path ";" command)))

compileマルチ文字列のbashスクリプトを使用する方法にも興味があります。

PATHに関する注意:(getenv "PATH")私が理解している限り、Xディスプレイマネージャー(xdm、gdm、kdmを含む)はXsessionの前にシェルを実行しないため、上記のソリューションでは使用しませんでした。そのため、GUIから実行されるemacsには異なる環境変数があります。バッシュのものから。私は起動時にcronを介して実行emacs --daemonし、パスはとに設定されている/etc/profileため~/.profile、EmacsはそこからPATHを取得しません。

Steve Purcellは、Emacsがシェルと同じ環境変数(PATHを含む)を持っていることを確認するためのコードを提案します(SOのバリアント12も参照)。

于 2012-07-26T10:12:00.747 に答える