現在のディレクトリにないファイルにこのスクリプトを適用できないのはなぜですか?

現在のディレクトリにないファイルにこのスクリプトを適用できないのはなぜですか?

~/bin/align-tablesemacs stackexchangeからこのスクリプトを取得しました。

#!/bin/sh
# -*- mode: shell-script -*-
#
# tangle files with org-mode
#
DIR=`pwd`
FILES=""

# wrap each argument in the code required to call tangle on it
for i in $@; do
FILES="$FILES \"$i\""
done

emacs -Q --batch \
--eval "(progn
     (require 'org)(require 'org-table)
     (mapc (lambda (file)
            (find-file (expand-file-name file \"$DIR\"))
            (org-table-map-tables 'org-table-align)
            (write-file file nil)
            (kill-buffer)) '($FILES)))"

.orgこのスクリプトをディレクトリ内のすべてのファイルに適用したいと思います~/foo。私の作業ディレクトリが/foo次の場合、リリースは$ align-tables *.org完全に機能します。ただし、別のディレクトリにある場合は$ align-tables ~/foo/*.orgエラーが発生します。

Opening output file: no such file or directory, ~/foo/foo/#bar.org#

エラーメッセージにターゲットディレクトリが2回リストされているので、スクリプトの対応する行に問題があると想定していますDIR='pwd'が、スクリプトを修正する方法がわかりません。

align-tables私の動機は、さまざまなディレクトリで動作するPerlプログラムを書いていることです。

私のスクリプトが協力する方法についてのアイデアはありますか?

ベストアンサー1

完全性を期すために、この問題はシェルで純粋に解決できます。

for i in "$@"; do
  pushd "$(dirname "$i")"
  DIR=`pwd`
  FILES="\"$(basename "$i")\""
  emacs -Q --batch \
    --eval "(progn
     (require 'org)(require 'org-table)
     (mapc (lambda (file)
            (find-file (expand-file-name file \"$DIR\"))
            (org-table-map-tables 'org-table-align)
            (write-file file nil)
            (kill-buffer)) '($FILES)))"
  popd
done

その後、各ファイルのインクルードディレクトリに変更され、相対emacsパス名を使用してその単一ファイルに対して既存のコマンドを実行してから再度切り替えます。

これは非効率的で間違っている可能性があります(特にelispを挿入するときに問題を引き起こす可能性がある奇妙なパス名*)。そして確かにemacs自体内にはより良い解決策がありますが、元のスクリプトと同じくらいうまくいきます。


* たとえば、次のようなファイルがあるとします。

"

引用符は文字通り含まれ、閉じる文字列リテラルとして扱われるため、 elisp スクリプトで構文エラーが発生します。他の人が存在するファイル名を制御できる場合は、任意のコードを実行するコードを生成できますが、そのファイル名がなくても問題が発生する可能性があります。

おすすめ記事