読者です 読者をやめる 読者になる 読者になる

Fedora 22 の dnf のメモ

Linux

概要

Fedora 22 からパッケージ管理システムが yum から dnf に変わる.

Workstation を見る限りでは yum も残っている.
# シンボリックリンクで dnf というわけではなさそう

dnf の使い方

// お約束の実行
# dnf update
# dnf upgrade

// Development Tools の入れ方も同じ
# dnf groupinstall "Development Tools"

基本的な使い方が大きく変っていない (?) ようでよかった

Makefile のメモ書き

Linux シェルスクリプト

概要

Makefile のメモ書き

subst でオブジェクトファイル名を生成する代わり

source = hoge.cpp fuga.cpp piyo.cpp

# 今まで subst でこう書いてた
objects = $(subst .cpp,.o,${source})

# これでもいい
objects = $(source:.cpp=.o) 

シェルスクリプトにおいてバックエンドで実行したコマンドの同期を取る方法

Linux シェルスクリプト

概要

シェルスクリプトでは wait コマンドにプロセス ID を指定することで同期がとれる

wait コマンドのサンプル

sleep コマンドをバックグラウンドで実行させ,wait コマンドで同期をとる
バックグランドで実行したコマンドのプロセス ID は $! で取得できる

#!/bin/bash

for ((i=0; i<3; i++))
do
  sleep 5 &
  array[i]=$!
  echo "Sleeping: ${i} : ${array[i]}"
done

wait ${array[@]}

echo "Finish!!"

シェルスクリプトで同期を取るサンプルコード

シェルスクリプト内で別のシェルスクリプトをバックグラウンドで実行し,終了の同期をとる
また,プロセス ID は重複しないはずなので配列の添字にも使える.

run.sh
#!/bin/bash                                                                     

./myshell1.sh &
array[$!]=$!
./myshell2.sh &
array[$!]=$!
./myshell3.sh &
array[$!]=$!

wait ${array[@]}

echo "Finish"
myshell{1, 2, 3}.sh
#!/bin/bash                                                                     

echo "$0: Sleeping..."
sleep 5
実行方法と結果
$ ./run.sh 
./myshell1.sh: Sleeping...
./myshell2.sh: Sleeping...
./myshell3.sh: Sleeping...
Finish

[余談] 別のファイルにしないでバックグラウンドで実行する場合

グループ化してバックグラウンドで実行すれば良い

#!/bin/bash                                                                     

{
    echo "Sleeping1..."
    sleep 5
} &
array[$!]=$!

{
    echo "Sleeping2..."
    sleep 5
} &
array[$!]=$!

{
    echo "Sleeping3..."
    sleep 5
} &
array[$!]=$!

wait ${array[@]}

echo "Finish"

LD_LIBRARY_PATH の設定方法をあれこれ考える

Linux シェルスクリプト

概要

シェルスクリプト内で LD_LIBRARY_PATH を設定することを考える.
LD_LIBRARY_PATH が設定されていない状態で,以下の方法で設定すると末尾に ":" がつくため気持ち悪い
// もちろん動作には影響を与えないので,問題はないはずだが...

#!/bin/bash

# LD_LIBRARY_PATH は空とする
export LD_LIBRARY_PATH=/usr/local/lib64:${LD_LIBRARY_PATH}
echo ${LD_LIBRARY_PATH}  # /usr/local/lib64: が表示されるはずだが,末尾の : が気になる

:${パラメータ:+<値>} を使う

パラメータが空文字以外に設定されている場合,パラメータに値を代入する

#!/bin/bash

LD_LIBRARY_PATH=/usr/local/lib64${LD_LIBRARY_PATH:+;}${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH

if でがんばる

if [ -z 文字列 ]; は文字列が空文字の場合に真になる

#!/bin/bash                                                                     

if [ -z ${LD_LIBRARY_PATH} ]; then
    export LD_LIBRARY_PATH=/usr/local/lib64
else
    export LD_LIBRARY_PATH=/usr/local/lib64:${LD_LIBRARY_PATH}
fi

[余談] : ${パラメータ:=<値>} を使う

パラメータが空の場合もしくは設定されていない場合に,パラメータに値を代入する
ただし,この方法ではパラメータに追加ができないので,LD_LIBRARY_PATH の設定には不向きである

#!/bin/bash                                                                     

: ${LD_LIBRARY_PATH:="/usr/local/lib64"}
export LD_LIBRARY_PATH

${パラメータ:-<値>} が上記と同じ動作となる

#!/bin/bash                                                                     

LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-/usr/local/lib64}
export LD_LIBRARY_PATH

PIPESTATUS でパイプラインの各コマンドの終了ステータスを取得する

Linux シェルスクリプト

概要

$PIPESTATUS を使うことでパイプラインの各コマンドの終了ステータスを取得できる.
ただし,使用できる環境には制限がある模様.

$? で終了ステータスを取得する場合の問題点

$? で終了ステータスを取得した場合は一番右のコマンドの終了ステータスを取得する.

$ ./configure 2>&1 | tee _configure.log
$ echo $? # tee の終了ステータスが表示される

$PIPESTATUS を使う場合

上記のサンプルで ./configure の終了ステータスをみたい場合は $PIPESTATUS を使う.

$ ./configure 2>&1 | tee _configure.log
$ echo ${PIPESTATUS[0]} # configure の終了ステータスが表示される


また,全コマンドの終了ステータスをまとめて取得したい場合は以下のようにする.

$ echo ${PIPESTATUS[@]}

$PIPESTATUS を使ったサンプルコード

#!/bin/bash

./configure 2>&1 | tee _configure.log
if [ ${PIPESTATUS[0]} = 0 ]; then
    echo "configure: success"
else
    echo "configure: failed"
    exit 1
fi

make 2>&1 | tee _make.log
if [ ${PIPESTATUS[0]} = 0 ]; then
    echo "make: success"
else
    echo "make: failed"
    exit 2
fi

make check 2>&1 | tee _make_check.log
if [ ${PIPESTATUS[0]} = 0 ]; then
    echo "make check: success"
else
    echo "make check: failed"
    exit 3
fi

make install 2>&1 | tee _make_install.log
if [ ${PIPESTATUS[0]} = 0 ]; then
    echo "make install: success"
else
    echo "make install: failed"
    exit 4
fi

[余談] がんばるのがダルイ ログだけが欲しい場合

グループ化してまとめてログを出すだけでもいいかもしれない

{
./configure
make
make check
make install
} 2>&1 | tee _build.log

firewalld のメモ書き

Linux ネットワーク

概要

CentOS7 で導入された firewalld のメモ書き

firewalld のメリット

  • ダイナミックに動作するので,ルール変更時などに通信を切断しなくて良い
  • ステートフルパケットインスペクションが可能
  • Zeroconf に対応

firewalld のゾーン

標準で以下の9つのゾーンが定義されている.

  1. drop
  2. block
  3. public
  4. external
  5. dmz
  6. work
  7. home
  8. internal
  9. trusted

各ゾーンのデフォルト設定ファイルは /usr/lib/firewalld/zones に格納されている.
実際に,設定をする際は firewall-cmd コマンドなどで /etc/firewalld/zones 配下のファイルを変更する.

# pwd
/usr/lib/firewalld/zones
# ls
block.xml  dmz.xml  drop.xml  external.xml  home.xml  internal.xml  public.xml  trusted.xml  work.xml

# pwd
/etc/firewalld/zones
# ls
public.xml  public.xml.old

設定ファイルの参照順序

以下の順番で参照される

  1. /etc/firewalld 配下
  2. /usr/lib/firewalld 配下

firewalld の起動と停止など

// 状態確認
# systemctl status firewalld

// 起動
# systemctl start firewalld

// 終了
# systemctl stop firewalld

// 設定ファイルの読み込み
# systemctl reload firewalld

// 有効にする
# systemctl enable firewalld

// 無効にする
# systemctl disable firewalld

// disable よりも強い無効化
# systemctl unmask firewalld

// unmask の取り消し
# systemctl mask firewalld

ゾーンとその設定の確認方法

// 現在のゾーンを確認する
# firewall-cmd --get-active-zone
public
  interfaces: enp0s25

// ゾーンの設定を確認する
# firewall-cmd --zone=public --list-all
public (default, active)
  interfaces: enp0s25
  sources: 
  services: dhcpv6-client ssh
  ports: 5000/tcp
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules: 

ゾーンにパケットの設定をする

// 5000番ポートを恒久的に通信を許可する
# firewall-cmd --zone=public --add-port=5000/tcp --permanent

// 恒久的にサービスを追加する
# firewall-cmd --zone=public --add-service=http --permanent