ひつじTips

技術系いろいろつまみ食います。

Shellの変数に文字列を連結すると,先頭から上書きされてしまう問題

小ネタですが,ハマったので......

f:id:mu-777:20220205184429p:plain
$ABは「aaaaabbb」になるはずでは......?😟

問題

タイトルの通りです.Shellの変数に文字列を連結すると,先頭から上書きされてしまいました.

上のスクショ通りですが,具体的には以下のようになります.

$ echo $A
aaaaa

$ AB=${A}bbb

$ echo $AB
bbbaa    # aaaaabbbになってほしいが,先頭から上書きされてしまう


原因

改行文字が原因でした.

実はA=aaaaaではなく,A=aaaaa\rとなっていたことでカーソルが先頭に戻ってしまい,先頭から上書きになっていました.

ということで,例えば以下のようにして”\r”を消してやると問題は解決します.

$  echo $A
aaaaa

# sedで'\r'を消す
$ A=`echo $A | sed 's/\r//g'`

$ echo $A
aaaaa    # echo した結果の見た目は変わらない

$ AB=${A}bbb

$ echo $AB
aaaaabbb    # aaaaabbbになった!


CRLFのCRの意味を知らなかった自分はだいぶダメっすね......

しょぼい話ではあるのですが,問題の現象(Shell変数に連結すると先頭から上書きされる)で調べて見つけられなかったので,ここに納めます🙏🙏

おまけ

この問題ですが,WSLでWindowsのコマンドで取得した文字列を加工しようとして踏みました.

具体的には,ホスト(Windows)にXサーバを立ててWSL2でX11アプリケーションを使う際,WSL上のDISPLAY変数にはホストのIPアドレスを指定してやる必要があります.

手動で設定するのがめんどいなぁと思ってたのですが,WSLならipconfig使える!と気づき, 以下のようにWindowsipconfig.exeを呼び出してDISPLAY変数に入れちゃえ,としたらハマりました.

# snip

HOST_IP=`ipconfig.exe | grep IPv4 | grep -v 172 | cut -d: -f2 | awk '{ print $1}'`
export DISPLAY=${HOST_IP}:0.0

# snip


$ source ~/.bashrc

$ echo $DISPLAY
:0.0168.0.2    # 192.168.0.2:0.0になってくれない😫


WSLはLinuxWindowsのハイブリッド感あって便利ですが,やっぱりWSLでWindowsの機能を使う場合は気をつけないとな......というお話でした