メモの日々


2017年12月13日(水) [長年日記]

[shell][howto] zshでPATHのような変数の値が重複しないようにする

zshにて環境変数PATHのようにコロン区切りの変数の値が重複しないようにしたい。

$ VAR=aaa:bbb:aaa

としたときに

$ echo $VAR
aaa:bbb

と振る舞って欲しいということ。 以前は「いい方法は見当たらなかった」と書いているがいい方法はある。

設定方法

組み込みコマンドのtypesetを使って

$ typeset -TU VAR var

とする。「var」の部分はほかの変数と同名にならなければ何でもよい。

-Tオプションで変数VARを配列変数varと関連づけ、-Uで重複除去の属性をセットしている。-Tは余計な設定に感じるが、これが無いと動作しない(少なくとも手元のzsh 4.3.11では)。

動作例

$ VAR=aaa:bbb:aaa
$ echo $VAR
aaa:bbb:aaa

$ typeset -TU VAR var
$ echo $VAR
aaa:bbb

$ VAR=ccc:ddd:ccc:ddd
$ echo $VAR
ccc:ddd

参考


2017年12月05日(火) [長年日記]

[windows] Windows 10で非管理者ユーザで環境変数を設定する

以前も同じことをメモしたけど手元の環境がWindows 10に変わっている。

以前のメモで「検索を使わずクリックだけでこの画面に辿り着く方法は分からない。」と書いていたが、次のようにすれば辿り着けることを知った。

  1. スタートボタンを右クリックして「コントロールパネル」をクリックする。
  2. コントロールパネルが開いたら「ユーザー アカウント」をクリックする。(コントロールパネルの「表示方法」が「カテゴリ」になっている場合は更に「ユーザー アカウント」をクリックする必要がある。)
  3. 画面左のメニューの一番下にある「環境変数の変更」をクリックする。

これで環境変数設定画面を開くことができる。ユーザアカウントの設定項目の中にあるとは思いつかなかった。


2017年11月21日(火) [長年日記]

[c][c++][dev] GCCの依存関係ファイル出力用のオプション

GCCには生成するオブジェクトファイルが依存しているファイル(ソースファイルとそこからincludeしているファイル)の情報をMakefileの形式で出力する機能があって、以前も少しメモしている。GCC 7.2のマニュアルだと

に説明がある。このオプションは覚えにくいので、自分が使うものだけ改めてメモしておく。

-MMD

-MMDオプションを指定すると、コンパイル時に依存関係を .d ファイルに出力してくれる。

このオプションを使った場合、.d ファイルに「システムヘッダファイル」は出力されない。システムヘッダファイルとは標準ライブラリのヘッダファイルなどだけれど、ヘッダファイルの探索ディレクトリ指定に -I の代わりに -isystem を使うとそのディレクトリ配下のヘッダファイルもシステムヘッダファイルとして扱われる。この仕組みを使えばBoostのような巨大なヘッダファイル群を .d ファイルに出力しないようにできる。

$ g++ src/main.cpp -o build/main.o -MMD && cat build/main.d
build/main.o: src/main.cpp src/a.h

-MP

-MPオプションを指定すると、.d ファイルにヘッダファイル用のターゲットも出力される。こうすると、ヘッダファイルを削除したときにコンパイルエラーになるのを防ぐことができる。

$ g++ src/main.cpp -o build/main.o -MMD -MP && cat build/main.d
build/main.o: src/main.cpp src/a.h

src/a.h:

-MF file

-MFオプションを指定すると、依存関係ファイルのファイル名を指定することができる。

$ g++ src/main.cpp -o build/main.o -MMD -MP -MF hello && cat hello
build/main.o: src/main.cpp src/a.h

src/a.h:

-MT target

-MTオプションを指定すると、.d ファイルに出力するターゲットファイル名を指定することができる。

$ g++ src/main.cpp -o build/main.o -MMD -MP -MT world && cat build/main.d
world: src/main.cpp src/a.h

src/a.h:

2017年11月17日(金) [長年日記]

[howto][shell][unix][soft] ワンライナーで同名ファイルへの上書き出力

シェルのリダイレクトを使って同名ファイルへの上書き出力を行うとファイルの中身が消えてしまう。

$ cat a
3
2
1
$ sort a > a
$ cat a

これを防ぐのにspongeというコマンドが使えることを知った。

$ cat a
3
2
1
$ sort a | sponge a
$ cat a
1
2
3

spongeはmoreutilsというツールコレクションの1つとして開発されているようで、moreutilsパッケージをインストールすれば使えるようになる。

ついでに、spongeコマンドを使ってやりたかった作業をメモ。

$ find . -name $PATTERN | xargs -I{} sh -c 'cut -f 1-2,4-44,47- {} | sponge {}'

パターンにマッチする全TSVファイルの3,45,46列目を削除したかった。


2017年11月15日(水) [長年日記]

[c#] WPFでGridSplitterを使ったときに行の高さがおかしくなる問題への対処

問題

次のXAMLのように、Gridの行にMinHeightを設定したWPFのウィンドウは大体思った通りに動作する。

<Window x:Class="GridSplitter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GridSplitter"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" MinHeight="250">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" MinHeight="80"/>
            <RowDefinition Height="5"/>
            <RowDefinition Height="*" MinHeight="80"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0"
                 Text="1&#xa;2&#xa;3&#xa;4&#xa;5&#xa;6&#xa;7&#xa;8&#xa;8&#xa;9"
                 VerticalScrollBarVisibility="Visible"/>
        <GridSplitter Grid.Row="1" HorizontalAlignment="Stretch"
                      ResizeBehavior="PreviousAndNext"/>
        <TextBox Grid.Row="2"
                 Text="1&#xa;2&#xa;3&#xa;4&#xa;5&#xa;6&#xa;7&#xa;8&#xa;8&#xa;9"
                 VerticalScrollBarVisibility="Visible"/>
    </Grid>
</Window>

しかし、

  1. 中央のGridSplitterをマウスで一番下までドラッグする。
  2. マウスドラッグによりウィンドウの高さを一番小さくする。

という操作をすると、下側のTextBoxがウィンドウをはみ出てしまい下スクロール用のボタンが表示されなくなってしまう。

下側TextBoxのスクロールバーの表示がおかしい

対処

Gridの行にMinHeightを設定するのをやめ、TextBoxを「高さ固定の行」と「高さ可変(*を指定)の行」にまたがって配置するようにすると、上記の操作をしてもTextBoxがウィンドウをはみでなくなった。

<Window x:Class="GlidSplitter2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GlidSplitter2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" MinHeight="250">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="80"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="5"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="80"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" Grid.RowSpan="2"
                 Text="1&#xa;2&#xa;3&#xa;4&#xa;5&#xa;6&#xa;7&#xa;8&#xa;8&#xa;9"
                 VerticalScrollBarVisibility="Visible"/>
        <GridSplitter Grid.Row="2" HorizontalAlignment="Stretch"
                      ResizeBehavior="PreviousAndNext"/>
        <TextBox Grid.Row="3" Grid.RowSpan="2"
                 Text="1&#xa;2&#xa;3&#xa;4&#xa;5&#xa;6&#xa;7&#xa;8&#xa;8&#xa;9"
                 VerticalScrollBarVisibility="Visible"/>
    </Grid>
</Window>

問題が解決

ただし、WindowのMinHeightを小さすぎる値(高さを指定している行が入りきらなくなる値?)に設定するとおかしな挙動が発生するので注意。