これが私の使用例です: コマンドライン ユーティリティは、コマンドラインでmelt
拡張子付きのファイル名を受け入れて.melt
開くことができます。例として、これは適切なtest_p.melt
ファイルです:
colour:blue
out=24
colour:red
out=48
... を開いて遊びますmelt test_p.melt
。
さて、問題は、.melt
ファイルがコメントをサポートしていないことです。コメントをサポートしていればよかったのですが ( などの引数を含む、解析できない引数を含む行に対してはエラー メッセージが表示されます#
)。コメント付きのtest_c.melt
ファイルは次のとおりです。
# master comment here
colour:blue # this is blue!
out=24
colour:red
out=48
これを直接開くとmelt
次のようになります:
$ melt test_c.melt
Failed to load "# master comment here"
...
...ブルースクリーンは表示されません。
そこで私は、コメントを投稿できると思ったのですともかく、そして Bash プロセス置換を使用して でファイルをフィルタリングしsed
、それをmelt
アプリケーションに提供するだけです。まず、 でテストを試みましたcat
。これは成功しました。
$ cat <(sed 's/#.*$//' test_c.melt)
colour:blue
out=24
colour:red
out=48
... いいね;しかし、これを で試すとmelt
、私の策略は見破られます:
$ melt <(sed 's/#.*$//' test_c.melt)
Failed to load "/dev/fd/62"
Failed to load "/dev/fd/62"
基本的に、melt はプロセス置換のために Bash が提供したパイプのファイル名を取得しますが、残念ながら、直接melt
処理しますargv[i]
。ファイルの場合は、.melt
ファイル名に拡張子が含まれている必要があります。拡張子が含まれていない場合、プロセスは失敗します。
そこで質問なのですが、プロセス置換をどのように使用すれば、パイプのファイル名に特定の拡張子(この場合は )を持たせることができるのでしょうか.melt
?基本的に、置換の結果として、 というパイプ ファイル名が必要になりますが/dev/fd/62.melt
、これは成功すると思います。
注: もちろん、いつでも次のことができます:
sed 's/#.*$//' test_c.melt > test_c_temp.melt
melt test_c_temp.melt
... しかし、まず、ここには 2 つのコマンドがあり、1 行のパイプラインが必要です。また、後で一時ファイルを削除することを考えなければならないという別の問題が発生しますが、これは好ましくありません。
これは、Bash プロセス置換、または何らかの方法で標準の Linux ツールで可能ですか?
答え1
可能性としては、melt
ファイルの変更されたコピーを表示するファイルシステムを指すことが挙げられます。ヒューズ通常のプログラムで実装され、権限を必要としないファイルシステムドライバを構築する一般的な方法です。多くのFUSEファイルシステム、そのうちの 1 つが役に立つ可能性は十分にあります。アイデアは、.melt
ファイルを読み取るときに「実際の」ファイルを読み取り、コメントを除外するマウント ポイントを提供することです。
スクリプトFS有望そうです (ただし、使用したことはありません)。次のようなものが機能するはずです:
mkdir ~/uncommented-melt
scriptfs -p "$HOME/bin/uncomment-melt;&*.melt" ~/work ~/uncommented-melt
ファイル~/work
はツリーのルートにあり、.melt
~/bin/uncomment-melt
#!/bin/sh
sed 's/#.*$//' "$1"
コメント付きのファイルがある場合は~/work/test_c.melt
、 を実行できますmelt ~/uncommented-melt/test_c.melt
。
その他の役立つ可能性のある FUSE ファイルシステム:
答え2
シェルでは、サフィックスを指定できるプロセス置換形式 (ファイルとパイプの代わりに一時ファイルを使用する形式)zsh
を使用できます。=(...)
/dev/fd/x
(TMPSUFFIX=.melt; melt =(sed 's/#.*$//' test_c.melt))
詳細については、info zsh TMPSUFFIX
(info
ページがインストールされていると仮定して、パッケージをインストールする必要がある可能性があります)を参照してください。zsh-doc
答え3
わかりました。私の特定のケースでは、これらの種類のメルト スクリプトは厳密にコマンド ライン引数として解釈される必要があることがわかりました。そのため、sed
OP のスクリプトだけでは十分ではありません (さらに、プロファイルなど、設定できる他のものもあります)。そのため、最終的に私が行ったことは次のとおりです。これは、OP のタイトルがカバーする他のケースのインスピレーションとして役立つ可能性があります。
最終的に、次のようにすることに決めました。test.shmelt
ファイル (実際にはbash
コメント付きのmelt
スクリプト コードを含むスクリプト) を作成し、このファイルを実行可能にしchmod +x test.shmelt
、スクリプトを編集した後、 として実行します./test.shmelt
。
test.melt
実行すると、に「クリーンアップされた」ファイルが作成され/tmp
、melt
代わりにこのファイルが呼び出されます。 はmelt
通常、プログラムの終了後もターミナルで実行され続けるため、SIGINT のトラップを使用すると、Ctrl-C が押されたときにこの一時ファイルをクリーンアップできます (ただし、クリーンアップする必要はありません)。
そうすれば、コメントが残り、ソース ファイルをすばやく編集して、melt を実行して結果を確認でき、また、コメントが「クリーンアップ」されたファイルも作成され、後で使用できるようになります。
のコードは次のとおりですtest.shmelt
:
#!/bin/bash
# call with: ./test.shmelt
#TMLTFILE="test.melt" # for final export
TMLTFILE="${0%%.shmelt}.melt" # for final export
function finished() { echo ; } ; # use this when testing or montaging to keep exported (tmp) .melt file; uncomment the below to remove the tmp file
#~ function finished() { rm /tmp/"$TMLTFILE"; echo "fin1 $0" ; } ; trap finished SIGINT ;
echo 'Remember `pulseaudio --start` to hear audio with `melt`!'
pulseaudio --check
if [ $? -ne 0 ]; then
pulseaudio --start
fi
DIRNAME=$(readlink -f $(dirname $0))
PROFILE="square_ntsc"
echo "
# the profile doesn't work from here;
# still has to be specified on command line
# but including it here so the path is saved for testing
#~ -profile
#~ ${PROFILE}
-video-track
# can avoid pixmap: here, but that s the producer;
# qimage: also works
# NB it is NOT '-out 1645'; but 'out=1645'!!
/media/myimg/%05d.bmp
in=0
out=1645
#~ length=1645
#~ loop=0
#~ eof=stop
-audio-track
/media/mysnd/snd.wav
in=0
out=1645
#~ loop=0
#~ eof=stop
#-consumer xml # doesn't work here
" | sed -e 's/#.*$//' -e 's/^[[:space:]]*//' -e '/^[[:space:]]*$/d' -e 's/[[:blank:]]*$//' > ${TMLTFILE}
# the sed: remove comments; remove indents; remove empty lines; remove spaces at end of line
# eof: one of: stop, loop, continue or pause (eof=stop)
# to loop, use `melt eof=loop ...` (but make sure first,
# that the edit as a whole stops - use xml to check!)
# due to caching issues, preview pieces (up to ~300 frames) like this:
melt eof=loop -profile ${PROFILE} ${TMLTFILE} in=200 out=400
# must have profile here, for checking w/ -consumer xml (else segfault)
# this command may add additional producers to the xml!:
## melt -profile ${PROFILE} ${TMLTFILE} -consumer xml
# use this to generate xml if needed:
#melt -profile ${PROFILE} $(cat ${TMLTFILE} | tr '\n' ' ') -consumer xml
# if exited normally, cleanup:
finished
答え4
しばらく経ちましたが、タイトルの質問に、私にとって役立つような形で答えてみたいと思います。
これは関連しています:一部のコマンドでは BASH プロセス置換が機能しないのはなぜですか?
私が解決しようとしていた具体的な問題は次のとおりです。
- 画像コンバーターを持っています。
- [ランダムな形式を挿入] から BMP/PNM/TGA などのシンプルな形式に変換します。
- JPEG に変換したいので、ImageMagick と連携する必要があります
convert
。 - 一時ファイルは使いたくありません。
残念ながら、このツールは出力ファイル名の拡張子から出力形式を導出するため、stdout/fds/pipes に出力できません。では、どうすればこれを回避できるのでしょうか?
適切な拡張子を持つシンボリック リンクを作成し/dev/fd/N
、それを「一時ファイル」として使用します。
例:
ln -s /dev/fd/4 temp.pnm
[TOOL] -i [INPUTFILE] -o temp.pnm 4>&1 | convert - [OUTPUT.JPG]