2012-07-26 41 views
5

我想運行以下bash腳本,該腳本存儲在Elisp字符串中,而不是在.sh文件中,然後將shell輸出存儲在變量中。從Emacs運行多字符串bash腳本

#!/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 

我無法在bash腳本上運行shell-command,它由多個字符串組成。 Emacs and Long Shell Commands也沒有幫助我,因爲compilecomint-run也需要命令,而不是bash語法。

如何從Elisp運行復雜的bash腳本?

+0

若爲MX殼命令的區域發生故障,請發送一個錯誤報告 – 2012-07-27 18:48:13

回答

6

多行命令的罰款,以提供作爲參數傳遞給bash -c,如果你說出來了,就像任何其他的shell參數可能包含shell元字符,例如:

(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))) 
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[@]}"即將結束不好,如果文件有可能被視爲在名稱分隔空格或其他字符。

+0

不,不管'arrayvar'的任何元素中是否存在shell元字符,''{{arrayvar [@]}''語法都是完全安全的。 – Sean 2012-07-26 11:36:49

0

shell-command實際上適用於多字符串bash語法。我的問題是shell-command不知道bash環境變量,包括PATH。我做了什麼:在腳本中將"全部替換爲\",並將其放入一個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))) 

我在如何使多串的bash腳本compile工作也仍然有興趣。

注意在PATH:我沒有在上述溶液中使用(getenv "PATH"),因爲據我瞭解,X顯示管理器(XDM包括,GDM和KDM)do not run shell before Xsession,所以從GUI運行的Emacs也會有不同來自bash的環境變量。我在啓動時通過cron運行emacs --daemon,我的路徑設置爲/etc/profile~/.profile,所以Emacs沒有從那裏獲取它的PATH。

Steve Purcell提出了一個code(另請參閱它的變體onetwo),以確保Emacs與shell具有相同的環境變量,包括PATH。