タグ別アーカイブ: bash

bash macOS

bash は大文字と小文字を厳格に区別する。
しかし macOS の bash は echo, pwd 等の大小文字を区別しない。
ところが if や変数名は普通に区別することに今頃気がつく。

shopt あたりにそうなるオプションが…無かった。
$- の値も Fedora と同じ himBH だった。
じゃあ何故大文字でも echo 等が使えるのだ?

解ってしまえば単純な話で。
組み込みコマンドではなく /bin/echo が使われていただけ。
ファイル名の大文字小文字を区別しないからこんな変なことになるんじゃ!

bash indirection

${!prefix*}
という記述で bash はその接頭子の変数名をブレース展開してくれるらしい。
ビックリマークは間接参照という意味らしい。

さっそくテストコードを書いてみたら見事にハマった!

#!/bin/sh

GF_top='心美 文緒 くおえ'
GF_loli='苗 睦 桃子'

echo ${!GF_*}

for gf in ${!GF_*}; do
    #for s in $gf; do
    for s in ${!gf}; do
        echo $s
    done
done

$gf という記述ではこの場合変数展開できない。
変数名で出力されるので ${${gf}} とかワケワカなことしてみたり。

よーく考えたら当然だった。
$gf なんて変数は定義していないんですもの。
どんな言語でもこんなことはできないよ。

なのでココでも間接参照で実際の変数を見つけてもらう必要がある。
シェルスクリプトって上記ができるとつい勘違いするよね、筆者だけ?

Gedit External Tools

Gedit で外部ツールからスクリプト実行を筆者はよく使う。
今まで ContentType で振り分けしていた。
しかしコレでは gjs, jjs や Python, Python3 で振り分けできない。

考えてみたらシバンで実行すればいいじゃん。
+x パーミッションを付けない状態でもシバンを読取りすればいいのだし。
先頭に #! があればソレで、無いなら今までどおりにすればいいかな。

#!/bin/sh

# シバンがあるならソレで起動、無いなら ContentType 判別

h=`head -n1 $GEDIT_CURRENT_DOCUMENT_PATH`
if [[ $h = \#\!* ]]; then
    app=${h#*\!}
    echo $app $GEDIT_CURRENT_DOCUMENT_PATH
    $app $GEDIT_CURRENT_DOCUMENT_PATH
else
    echo @ContentType $GEDIT_CURRENT_DOCUMENT_TYPE
    if [[ $GEDIT_CURRENT_DOCUMENT_TYPE = *python ]]; then
        python3 $GEDIT_CURRENT_DOCUMENT_PATH
    elif [[ $GEDIT_CURRENT_DOCUMENT_TYPE = *javascript ]]; then
        gjs $GEDIT_CURRENT_DOCUMENT_PATH
    elif [[ $GEDIT_CURRENT_DOCUMENT_TYPE = *shellscript ]]; then
        sh $GEDIT_CURRENT_DOCUMENT_PATH
    elif [[ $GEDIT_CURRENT_DOCUMENT_TYPE = *vala ]]; then
        vala $GEDIT_CURRENT_DOCUMENT_PATH
    elif [[ $GEDIT_CURRENT_DOCUMENT_TYPE = *csrc ]]; then
        src=`head $GEDIT_CURRENT_DOCUMENT_PATH`
        case $src in
            *gtk.h*)
                echo "Gtk Build"
                gcc $GEDIT_CURRENT_DOCUMENT_PATH `pkg-config --cflags --libs gtk+-3.0` ;;
            *glib.h*)
                echo "GLib Build"
                gcc $GEDIT_CURRENT_DOCUMENT_PATH `pkg-config --cflags --libs glib-2.0` ;;
            *)
                echo "Gcc Build"
                gcc $GEDIT_CURRENT_DOCUMENT_PATH ;;
        esac
    else
        echo Non Support File
    fi
fi

これでもし他のスクリプト言語に目覚めてもシバンだけで対応できるぞ!
無いと思うけど。

bash =~

sh では存在しないコマンドを打つとなんか調べてくれる。
あれは command-not-found というものが行っているらしい。

Linux入門はじめますた: おせっかいな「command not found」

Fedora 25 で調べると以下のバイナリだった。
/usr/libexec/pk-command-not-found

ハンドラの定義は set コマンドで見ることができる。
随分違うなぁ、まあ 7 年も前の記事ですし。

どっちにしろ無効にしたい場合はやることは同じ。
command_not_found_handle 関数を ~/.bashrc で上書き…

いやチョットまて?

=~ 演算子って何だ!!!

Man page of BASH

にて =~ でページ内検索でなんとか。
正規表現マッチってことみたい。

だけど上記関数は i という文字が含まれているかどうかだけだよな?
それなら単純に文字列が含まれているかどうかも解るかも。

おぉ、Python の文字列 in 演算子のように使えるジャン!
こんな便利な使い方が検索で全然出てこないのは何故だYO!

file-roller command

忘れるところだった。
以前のように形式自由でアーカイブ可能な Nautilus Script を作らないと!

筆者は「新しくなったことを全否定する老人は死ね」な人間である。
でも今回は否定させて、だってデフォルトの機能では tar.gz が無いんだ。

7z なんて Kivy がソレで配布されていて mac でスゲー困ったし使いたくない。
GNOME はあの3形式以外は使ってほしく無いのかもだが流石に無理。
サルな人はすぐ昔のバージョンに戻そうとする、筆者は作る。

でも多数のアーカイブ形式に対応するって大変そう。
と思うけど実はもうソレをやっているものがあるんです。
file-roller はコマンドとして使えます。

file_roller

–add-to オプションで拡張子を指定すれば自動判別でアーカイブしてくれる。
ということでこんなシェルスクリプトを、拡張子のとうりな形式になります。

#!/bin/sh

path=`pwd`
name=${path##*/}
file-roller --add-to="${name}.tar.gz" "$@"

で。
Nautilus Script にコピーして送ってみる。

targz

これだけでで半角スペース及び日本語に対応。
以前と同じく親ディレクトリ名でアーカイブされる。

コレを Gjs なんかを使って GUI を以前みたく作って実行させればいい。
と思ったけどなんかコレで充分な気がしてきた。
Comipoli もやんなきゃいけないし、後は気が向いたら。

追記

下記だけで以前のダイアログが出せる、何を今頃だけど。

#!/bin/sh
file-roller --add "$@"