最近,たいていのことは MacBook でやっているのだが,Stable Diffusion で大量のファイルをあつかっていて,それを iCloud に退避することが必須になっている. そのファイルを zsh のコマンドラインであつかおうとすると,あたまのいたい問題がおこる. iCoud のファイルが空白をふくむディレクトリ "~/Library/Mobile Documents/com~apple~CloudDocs/" にマウントされるからだ. これを zsh であつかうには至難の技がもとめられる. なぜこんな,おかしななまえにしたのだろう?
zsh で
shell1 ~/Library/Mobile Documents/com~apple~CloudDocs/とすると shell1 はこのディレクトリ名を 1 個の引数としてうけとる.つまり,shell1 のなかで $1 は "~/Library/Mobile Documents/com~apple~CloudDocs/" となる.ところが,shell1 から shell2 をよぶときに
shell2 $1とすると,shell2 にわたされた 1 個の引数が $1, $2 に分割されて,$1 には "~/Library/Mobile", $2 には "Documents/com~apple~CloudDocs/" がわたされる.つまり,ディレクトリ名が空白の部分で分割されてしまう.
もっとこまったのは,shell1 のなかで $@ をつかうと,すでにひとつの要素ではなく"~/Library/Mobile" と "Documents/com~apple~CloudDocs/" からなるリストになっていることだ. つまり,$@ は $1, $2, ... のリストだという常識がくずれている. したがって,引数ごとの処理のためにつぎのコマンド列をつかうことができない.
for arg in @$; do ... doneこうすると $arg にはこのループの最初のくりかえしで "~/Library/Mobile",2 回目のくりかえしで "Documents/com~apple~CloudDocs/" がはいるからだ. これではまともなループ処理ができない.
そこで,やむなく,かわりにつぎのようなコマンド列をつかっている.
if [[ "$1" ]]; then ... fi if [[ "$2" ]]; then ... fi ...これでは比較的少数の引数しかあつかえないが,やむをえない.
コマンドラインから直接よぶシェルスクリプトと,そこから間接的によぶシェルスクリプトとで引数がちがうあつかいをうける. そこで,シェルスクリプトを 2 種類にわけて,表のスクリプト shell は裏のスクリプト shell_1 をよぶだけにしている.
./shell_1 $1間接的によぶスクリプトにはなまえに "_1" をつけている. これでやっと統一的なあつかいができるようになった.