タグ別アーカイブ: bash

Gedit External Tools CRLF

Gedit の External Tools が変だ。

何故コマンドが改行されているのだ?
head コマンドの挙動が変わってしまったのだろうか。

一時間くらいすったもんだしてやっと理由が判明。
何故か改行コードが CRLF になっていたからだった。

head -n1 は LF までを戻すので直前の CR は残ってしまうみたい。
てか bash が CR を改行と認識すると初めて知った。
CR を使うなですむ話だけど、一応対策。

#!/bin/sh

# Do shebang

#h=`head -n1 $GEDIT_CURRENT_DOCUMENT_PATH`
# Remove CR
h=`head -n1 $GEDIT_CURRENT_DOCUMENT_PATH | tr -d '\r'`
if [[ $h = \#\!* ]]; then
    app=${h#*\!}
    echo $app $GEDIT_CURRENT_DOCUMENT_PATH
    $app $GEDIT_CURRENT_DOCUMENT_PATH
fi

普段はまったく無意味な処理なんだけどね。

read command

read コマンドはファイルを読み出せると今頃知った。
いやまあ、この人と同じようなことをやろうとしたら下のほうに。

sh – IFSに改行のみを指定したい – スタック・オーバーフロー

早速実験コードを書いてみたらあら大変。
アスタリスクが展開されているしインデントが消えている。
運よく C 言語ソースの読み込みで試したおかげで即解った。

bashで * が意図しないワイルドカード展開される場合の対処 – 座敷牢日誌

read だとシェルと同じワイルドカード展開をしてしまうのか。
そういうものだと思うしか無いけど。

readするときはIFS=を付けておくとstrictな感じで気持ちが良い – Qiita

while IFS= なんて手段があったのか!
早速試したけどマジでデフォルトに影響しないんだね。
後で IFS をデフォルトに書き戻す必要が無いってこと。

ということで先頭数文字をオフセットして書き出すスクリプトでも。
ちなみに空行でもスルーしてくれるので文字列長を得る必要は無い。

#!/bin/sh

# 先頭の何文字かをオフセットして出力する bash スクリプト
# [スクリプトファイル名] [オフセットしたい数値] [ファイル名]
# 書き出しはリダイレクトを使う

if [[ $# -lt 2 ]]; then
    echo $0 [オフセットしたい数値] [ファイル名]
else
    while IFS= read -r line; do
        echo "${line:$1}"
    done < $2
fi

# @ for
#_IFS=$IFS
#IFS=$'\n'
#lines=`cat $2`
#for line in $lines; do
#    echo ${line:$1}
#done
#IFS=$_IFS

短っ!

正直スクリプトなんて思ったとおりに動けばそれで充分なんだけどさ。
ココまでスッキリするとチョッピリ嬉しいですね。

連番ファイルのダウンロード

とあるサイトの連番ファイルをダウンロードしたくなった。
んで、そんなの bash シェルスクリプトが使える環境 (macOS, Linux) なら超簡単で。

#!/bin/sh

# 001.jpg - 200.jpg だった場合
for (( i=1; i<201; i++ )); do
    n=`printf %03d.jpg $i`
    wget http://なんちゃらどっとこむ/${n}.jpg
done

# 1.jpg - 200.jpg だった場合
#for (( i=1; i<201; i++ )); do
#    wget http://なんちゃらどっとこむ/${i}.jpg
#done

以上。

なんだよこの for 文は使い道があるじゃないの!
wget コマンドは一部ディストリビューションでは dnf や apt で。
google-chrome が使っているから依存関係で勝手に入るはずだけーがさ。

エロゲ専用に落ちぶれた某 OS はアプリや拡張を使うんでしょ?
プログラミングができないサルだけがいまだに使っている OS だよねwwwwww

いや、せっかくだからサイトの JPEG リンク抜き出しをやりたいぞ。
とりあえず URL を読み込んで、それから

href="空白のない文字列jpeg"

を正規表現で抜き出して slice すれば簡単に wget できそうだ。
Python3 の urllib を使えばアホみたく簡単そうだけど、あえて gjs で。

#!/usr/bin/gjs

const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;

if (ARGV.length == 0) {
    print("URL を指定してください");
} else {
    let file = Gio.File.new_for_uri(ARGV[0]);
    let fstream = file.read(null);
    let dstream = new Gio.DataInputStream({base_stream: fstream});
    for (;;) {
        let [val, len] = dstream.read_line_utf8(null);
        if (val.match(/\<\/html\>/gi) !== null)
            break;
        // href="空白のない文字列jpeg" の取得
        let links = val.match(/href=[\'|"]\S+(jpg|jpeg)[\'|"]/gi);
        if (links !== null) {
            for (let link of links) {
                let url = link.slice(6, link.length - 1);
                print(`${url} を取得します`);
                GLib.spawn_command_line_async(`wget ${url}`);
            }
        }
    }
}
//ex: ft=js

書いてみた。

相対パスの場合はガン無視だけど昨今は WordPress ベースが大半だしこれでいいか。
つか相対パスにしている人はそもそも連番ばかりなので最初のでいい。

テキトーなエロ画像サイトで上記を試す。
普通にダウンロードされた、後はリネームして順番を合わせるだけ。
自分が書いたコードが思った通りに動くって本当に面白い。

gvfs-open to gio open

Fedora 26 では gvfs-open が非推奨になっていた。

man gio で見ると gvfs-*** コマンドが全部まとめられたようだ。
ぶっちゃけ xdg-*** だけでイイじゃんみたいなものだったし。
UNIX らしくないかもだけど筆者はコッチのほうがいい。

gvfs-open と同じなんだけど少し違うようだ。

Nautilus Window を開いた状態でないとパス名を開けない。
Gedit Window を開いた状態でないとテキストファイルを開けない。

http://localhost/ や画像なんかは普通にデフォルトアプリが立ち上がる。
自作アプリにデフォルトを変更した動画や CBZ も自作アプリが立ち上がる。

多分バグではなく仕様だと思うんだけど、よくわからない。
とりあえずウインドウを開いておけば今迄どおり使えるってことで。

bash macOS

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

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

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