しぇる、シェル、SHELL、TIPS、Linux

最近、物覚えが、これまで以上に、悪くなりつつある?


#001 ループ

bashの場合)

for i in 1 2 3; do
echo $i
done

tcshの場合)

foreach i ( 1 2 3 )
echo $i
end


#002 文字列を含むファイルの検索

$ find . -print0 | xargs -0 grep "strings"
↓ /tmp以下のcoreファイルを削除
$ find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
↓だとファイル名が表示される
$ find . -print | xargs grep "strings"
↓だとファイル名が表示されない
$ find . -print | xargs -n 1 grep "strings"
↓だとファイル名が表示される
$ find . -print | xargs -n 1 grep -H "strings"
↓でパーミッション755のファイルを検索
$ find . -perm 755
↓でパーミッション444のファイルをAND検索
$ find . -perm -444
↓でパーミッション111のファイルをOR検索
$ find . -perm +111
↓でパーミッション111のファイルを../binにコピー
$ find . -perm +111 -type f -exec cp {} ../bin \;
↓で実行可能ファイルを../binにコピー
$ find . -executable -type f -exec cp {} ../bin \;
↓で拡張子.cを除くファイルを検索
$ find / \! -name "*.c" -print
↓でfind結果をソートしてgrep
$ find . -name "*.txt" -print | sort | xargs grep "hoge"
$ find . -name "*.txt" -print0 | sort -z | xargs -r0 grep "hoge"


#003 awk で指定フィールドを出力

$  awk -F : {'print $5;'} /etc/passwd
※コロンで区切られた場合
$ grep hoge foo.txt | awk -F " " '{print $3, $4;}'
※スペースで区切られた場合
$ awk -F '\t' '{print $11, $1}' hoge.txt > active.smi
※タブで区切られた場合


#004 ループ while

(bash)

bash-3.2$ i=1
bash-3.2$ while [ $i -le 3 ]; do
> echo $i
> i=`expr $i + 1`
> done
1
2
3
bash-3.2$ 

(tcsh)

[eta:~] foo% set n=1
[eta:~] foo% while ($n <= 3)
while? echo $n
while? @ n = $n + 2
while? @ n--
while? end
1
2
3
[eta:~] foo% 


#005 文字コードの変換 iconv
EUC-JPからUTF-8へ変換

% iconv -f EUC-JP -t UTF-8 hoge.txt > out.txt


#006 grepで複数のパターンマッチを表示
正規表現で指定する

% grep -E X11\|host\|user sample.txt
※ -Hオプション : 出力中にファイル名を含める
ファイル名を出力
$ grep -H hoge *.txt

正規表現で
空白行: ^$
行全体: ^.*$

例、コメント行と空白行を削除
$ grep -E -v '^#|^$' sample.txt


#007 rpmの中身を抽出
rpm2cpioを使う。

% rpm2cpio pkgname.rpm | cpio -ivd

次のコマンドでパッケージ内容をリスト表示

% rpm -ql pkgname


#008 EOFでファイル出力、Here documents/strings
ヒアドキュメント

#!/bin/csh
cat > .machines <<EOF
node01
node02
EOF

シェル変数($)を展開しない場合は、
最初のEOFをクオーテーションで囲む。
例
cat > .machines <<'EOF'


追加する場合は、cat >>とする<<-wordsとすると文字列前のタブを削除<<


#009 teeで標準&エラー&ファイル出力

sh/bash
$ cat /etc/hosts 2>&1 | tee hosts.txt
csh/tcsh
$ cat hoge |& tee output
teeを使わず、ファイルに出力する場合、
$ cat /etc/hosts > hosts.txt 2>&1 (sh/bash)
$ cat /etc/hosts >& hosts.txt (csh/tcsh)
別々のファイルへ出力
$ cat xxx yyy 1> error.txt 2> output.txt (sh/bash)
$ ( cat xxx yyy > output.txt ) >& error.txt (csh/tcsh)


#010 自動ログアウトの無効化

$ unset autologout

または

$ export TMOUT=0 


#011 sftpでポート指定

$ sftp -oPort=8822 username@hostname.domain

#012 Gnome フォルダをブラウザモードで起動
(フォルダ毎にウィンドウが起動されるのを防ぐ)
System > Preferences > File Management とし、プロパティダイアログを開く、
Behaviorタブの『Always open in browser windowsチェックボックスを有効に。


#013 Gnome タスクトレイのウィンドウリストの表示方法を変える
(タスクトレイの空スペースがなくなった場合、グルーピングする)
ウィンドウリスト左端で右クリック、Preferencesを選択する。
ダイアログ内の『Group windows when space is limited』を有効に。
もしくは、
タスクトレイ右クック、Add to Panel...で、『Window Selector』を追加。


#014 シェル関数の定義と実行
スクリプト例)

#!/bin/sh

# definition of function
testfunc() {
   echo "this is a test function."
   return 0
}

# execution of function
testfunc

exit

引数はそのまま渡せる。


#!/bin/sh
func_test ()
{
echo "$1"
}

func_test abc

別ファイルに定義した場合、sourceでインポート可。



#015 Makefile中でawkの引数を指定
'$'を重ねる。awkに限らず、シェル変数でも?

mkdat:
        awk -F " " {'print $$4;'} $(LOG)
        echo $${PWD##*/}


#016 sedでファイル内の文字列置換

$ sed -i -e s/perfect/stupid/g sample.txt
複数ファイルを一括処理する場合、
$ ls *.txt | xargs sed -i -e s/perfect/stupid/g
などとすればOK。
$ grep -lI "stupid" * | xargs sed -i -e s/stupid/perfect/g
とすれば、ある文字列を含み、かつバイナリファイルを除くファイルに対してのみ、文字列を置換する。
strを含むファイルをfindして、strをSTRに置換する。
$ find . -print0 | xargs -0 grep -l str | xargs sed -i -e s/str/STR/g
上に同じだが、レギュラーファイルで、ファイル名最後が.bakとなっているものを除き、置換する。
$ find . -type f  \! -name "*.bak" -print0 | xargs -0 grep -l str | xargs sed -i -e s/str/STR/g


↓は、一時ファイルを使用する方法
for i in *.f; do cp $i $i.bak; sed -e "s/perfect/stupid/g" $i.bak > $i; done

1行目に文字列を挿入
$ sed -i -e "1i %chk=test.chk" sample.com
(置換)
$ sed -i -e "1s/^/%chk=test.chk/" sample.com


3行目に文字列を挿入
$ sed -i -e "3a comment" sample.com

stringsを含む行の次行に文字列を挿入
$ sed -i -e "/strings/a hello" sample.com


#017 1階層下のサブディレクトリの使用量を調べる

$ du -h --max-depth=1 .
Mac OS Xの場合
$ du -h -d 1 .


#018 IPマスカレード
例 eth1:global, eth0:local

# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.0/24 -j MASQUERADE


#019 パーティションチェック

# fdisk -l


#020 ターミナルの初期化

画面がおかしくなった時に、

# reset


#021 ssh backdoor
\-Rオプションで接続先リモートサーバのポートを接続元ホストのsshポートにフォワーディング

target : $ ssh -R 8888:localhost:22 relay.net
relay  : $ while [ 1 ]; do date; sleep 300; done
※ssh接続を維持し、別の端末からrelayにログイン
relay  : $ ssh -p 8888 localhost
※予めecho ServerAliveInterval 150 >> ~/.ssh/configとしておけば、2行目whileは不用
※もしくは、ssh実行時に-o "ServerAliveInterval 150"オプションを追加し、接続
スポットで処理する場合、手元の外部マシンから、
$ ssh -f -2 -N -L 8888:target.net:22 relay.net
$ ssh -p 8888 localhost
などとすればよい。一つ目のsshがbackgroundで動作し続けるので、
作業後は要kill


#022 screenコマンド
ターミナルを共有

$ screen -S mywin
別のターミナルから、次のコマンドでアタッチ
$ screen -x mywin
C-a C-dでデタッチ
$ screen -ls または -list
で、screenセッションをリスト
$ screen -r mywin または プロセスID
で、リタッチ。
C-a C-nまたはC-a C-pでスクリーン切り替え
C-a,C-\でquit
~/.screenrcで以下を定義しキーバインドをaからhに変更
escape ^hH
デタッチしてリアタッチ
$ screen -d -r mywin
$ screen -d -R mywin
$ screen -d -RR mywin
$ screen -D -r mywin
$ screen -D -R mywin
$ screen -D -RR mywin


#023 シェルの戻り値、シェル変数
$?に格納される。

#!/bin/sh
ls hoge
if [ $? -eq 0 ]; then
      echo success
else
      echo failed
      exit 1
fi

また、次のような変数も。

$0 : 実行ファイル名
$$ : プロセスID
シェルスクリプト内では、次の変数を利用可
$# : 実行時引数の数
$* : 引数をすべて表示(スペース区切り)
$@ : 引数をすべて表示(クオーテーション展開が異なる)
$1〜n : n番目の引数

#024 firefox3でjavaappletを有効にする

1. jreをインストール
2. ln -s /usr/java/jre*/lib/*/libnpjp2.so ~/.mozilla/plugins/

Ref. http://plugindoc.mozdev.org/linux-amd64.html#java-sun


#025 fuserでファイルを掴んでるプロセスを調べる

$ /sbin/fuser -v filename


#025 ssh+tarによるファイル転送

$ tar zcf - /src | ssh targethost tar zxf - -C /dist

#026 sortコマンド

数値順に並べ替える
$ sort -rn filename
ソートキーの指定
$ sort -n -k +4 filename
指数列を扱う(-nのかわりに-g)
$ sort -g -k 2 filename 


#027 sed コマンド

-n, パターンスペースの自動表示を抑制
-r, スクリプト内で拡張正規表現を使用

指定行のみ表示(10〜20行)
$ sed -n '10,20p' filename
指定行から最終行まで表示(15〜最終行)
$ sed -n '15,$p' filename
指定行のみ表示(1行と100行)
$ sed -n -e '1p' -e '100p' filename
ある文字列を含む行のみを表示
$ sed -n -e '/abc/p' filename
ある文字列を含む行を削除
$ sed -e '/abc/d' filename
指定行範囲の文字列を置換(10〜20行)
$ sed -e '10,20s/abc/ABC/'
指定行範囲の文字列を置換(10〜20行)
$ sed -e '10,20s/abc/ABC/'
指定行範囲の文字列を置換して部分表示(10〜20行)
$ sed -n -e '10,20s/abc/ABC/p'


#028 viで"\"を改行コードに置換する

%s/\\/\r/g


#029 viでウィンドウ分割

C-w + sで水平分割(または、:sp)
C-w + vで垂直分割(または、:vsp)
C-w + nで新規ウィンドウ追加(または、:new)
C-w + j,k,h,lでカーソル移動
C-w + oでカレントウィンドウのみ表示(または、:only)
C-w + qでカレントウィンドウを閉じる(または、:quit)
:qallで全ウィンドウを一度に閉じる
C-w + rでウィンドウ入れ替え
C-w + Rでウィンドウ入れ替え(逆方向)


あれ、O'ReillyのLearning the vi Editor、↓で読める。。
ありがたいー

Learning the vi Editor
http://www.samgeneration.com/Book/unix2.1/vi/index.htm


#030 gcc動作チェック

$ echo 'int main() { return 0; }' | gcc -xc - ; echo $?


#031 Live CDで WARNING: Cannot find root file system!エラー


#032 CentOS/Scientific Linuxでopenbabelやpymolをインストール

epelリポジトリを追加する。
epel-release.noarch : Extra Packages for Enterprise Linux repository configuration

# yum install epel-release
# yum search openbabel pymol

epel-testingリポジトリは無効化されているので、ファイルを書き換えるか、
等として有効化して利用する。

# yum --enable-repo=epel-testing install packagename

rpmコマンドで該当するrpmを追加してもOK
# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-3.noarch.rpm


#033 FTPインストール

例)
FTP site name: ftp.yz.yamagata-u.ac.jp
directory : pub/linux/centos/5.5/os/i386
※このディレクトリには、images,isolinux,repodataなどがある。


#034 ファイルシステムのチェック&リペア(fsck
ntfsckやfsck.vfat等を使う。
Windowschkdskが止まっていたが、LiveUSBのntfsckで復旧できた(先に進んだ)。幸運?


#035 テキストファイル内の単語のカウント

$ cat sample.txt | tr ' ' '\n' | sort | uniq -c | sort -nr | head


#036 awkで足し算

$ awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}' num.txt

あるプロセスのメモリ使用サイズRSS(Resident Set Size)を調べる

$ cat /proc/PID/smaps | grep Rss | awk 'BEGIN{mem=0}{mem+=$1}END{print mem}'

ちなみに、Rss=Private_{Clean,Dirty}+Shared_{Clean,Dirty}。
パターンstringsのマッチ数を表示

$ awk '/strings/{++x}END{print x}' target.txt

xはBEGINで初期化した方がよいかも。


#037 ディストリビューションのチェック

$ find /etc -maxdepth 1 -type f \( -name "*-release" -o -name "*_version" \) -print -exec cat {} \;

または、

$ cat /etc/issue


#038 Nouveauの停止
カーネルパラメータにnouveau.modeset=0を追加する


#039 rpmデータベースのリビルド

# cd /var/lib
# cp -a rpm rpm.bak
# cd rpm
# rm __db.*
# rpm --rebuilddb


#040 reverse-i-search
プロンプトでCtrl+Rキー、文字列入力でhisotryからコマンド履歴サーチ。
Enterで実行、Tabでコマンド表示、Ctrl+Rで再検索


#041 シェル文字変数の操作(bash)

前方一致文字列を削除(残った値を表示する)


${i#abc*}
${i##abc*}
#が1個だと最短一致、2個だと最長一致、ワイルドカード使用可
例, カレントディレクトリ名を表示
$ echo ${PWD##*/}
前方、後方一致を同時に展開することはできない模様。
素直に一時変数を介して、処理するのがよいはず。
※"*/"でそのディレクトリより上のパスがマッチ
tcshだと、${PWD:t}

例, fに/path/string.txtが代入されていてstringのみ取り出したい場合
s=${f##*/}
echo ${s%.txt}

関連、basenameコマンド。
Examples:
basename /usr/bin/sort -> "sort"
basename include/stdio.h .h -> "stdio"
basename -s .h include/stdio.h -> "stdio"
basename -a any/str1 any/str2 -> "str1" followed by "str2


後方一致文字列を削除


${i%*xyz}
${i%%*xyz}
%が1個だと最短一致、2個だと最長一致、ワイルドカード使用可
tcshだと、$i:rで拡張子を削除

一致文字列を置換(shでは動作しないので、bashを使用)


${i/abc/xyz}
${i//abc/xyz}
はじめの/が1個だと最短一致、2個だと最長一致、ワイルドカード使用可


#042 ファイルシステムのラベル/UUIDを調べる、付与する

ext2/ext3で利用可。


確認
# e2label /dev/sda1
# tune2fs -l /dev/sda1
# dumpe2fs -h /dev/sda1
付与
# e2label /dev/sda1 hoge
# tune2fs -U c1b9d5a2-f162-11cf-9ece-0020afc76f16 /dev/sda1

#043 grub tips
centosgrubが古いためか、fedoraカーネルイメージをロードできない


sdaにcentos、sdbにfedoraとしている場合、
fedoraをどうにか起動して(※)、次の手順でsdaのmbrgrubをインストールする。

# mkdir /mnt/boot
# mount /dev/sda1 /mnt/boot
# grub-install --root-directory=/mnt /dev/sda

(*) 起動例

grub> root (hd1,0)
grub> kernel /vmlinuz-2.6.33.6-147.2.4.fc13.x86_64 ro root=/dev/mapper/VolGroup-lv_root
grub> initrd /initramfs-2.6.33.6-147.2.4.fc13.x86_64.img
grub> boot

※参照されるgrub.confは、/mnt/boot/grub/grub.conf


#044 キーボードマップの変更


(redhad系)
/etc/sysconfig/keyboard
のKEYTABLEの値を変える。
変更前)KEYTABLE="us"
変更後)KEYTABLE="jp106"
※テーブルファイルは、例えば、次のディレクトリ以下にある。
/lib/kbd/keymaps/i386/qwerty/
関連コマンド?
keymaps, loadkeys, dumpkeys, showkey, xmodmap


#045 rpmパッケージをフルネームで表示(フォーマット指定)


$ rpm -qa --qf="%{n}-%{v}-%{r}.%{arch}.rpm\n" | grep fc | sort


#046 ジョブ制御、コントロール、逐次実行


$ command1 ; command2 // 逐次実行
$ command1 && command2 // command1正常終了時、command2実行
$ command1 || command2 // command1以上終了時、command2実行
$ ( command1 ; command2 ) & // 逐次実行をバックグラウンド実行

#047 ネットワークカード設定の確認


# /sbin/ethtool eth0

#048 ファイルを残してgzip

オプション-cで標準出力に書き出し、リダイレクト


$ gzip -c file > file.gz
$ gzip -c -d file.gz > file
zipコマンドでは、

$ zip file.zip file
$ zip [-r] archive file


#049 Unix in a Nutshell

http://docstore.mik.ua/orelly/unix/unixnut/index.htm


#050 vi エディタで列の削除


方法1、Visual モードを使う
例えば、2列目から先を全部消す場合
1, カーソルを1行目の2列目頭にあわせる。
2, Ctrl + vキーを押し、Visualモードに
3, Gキーで最下行へ
4, $キーで行末へ
5, ddキーを押し削除


方法2、mapを使う
例えば、3列目から5列目を削除する場合、カーソルを1行目に移動して、
1, :map K 02Wd3WjK
※意味は、"行頭に行って(0)、2Word進んで(2W)、3Word消して(d3W)、1行下に降りて(j)"、を繰り返す(K)
2, Kキー押下


#051 複数行にわたるデータについて、部分的に改行を削除したい

viエディタのJコマンド(カーソル行の改行を削除)と:mapを組み合わせる。
例えば、次のようなデータ。


$ cat data
X1 Y1 Y2 Y3
Y4 Y5 Y6
Y7 Y8 Y9
X2 Y1 Y2 Y3
Y4 Y5 Y6
Y7 Y8 Y9
...


$ vi data
:map K 3JjK
1Gとして、Kを実行。

すると、3n+1,3n+2行(n=0,1,2...)の改行が削除され、次のようになる。


X1 Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9
X2 Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9
...


#052 RPMforgeレポジトリの追加

http://packages.sw.be/rpmforge-release/
から、該当するrpmforge-release-*.rpmをDL&Install


#053 シェルの確認


カレントシェル
$ ps $$
$ echo $0
ログインシェル
$ env | grep SHELL

#054 連続スペースのあるファイルをcutで抽出


sedで単一スペースにして、列データを抽出
$ cat hoge.txt | sed 's/\s *//g' | cut -d ' ' -f3
一部の行を削除する場合、例えば3〜5行
$ cat hoge.txt | sed -e '3,5d'
一部の行のみを表示する場合、例えば2〜4行
$ cat hoge.txt | sed -n -e '2,4p'


#055 Xサーバの拡張モジュールを調べる

X11フォワーディングでエラーになった場合などに。


$ xdpyinfo


#056 smartctlの使用例


# smartctl -s on /dev/sda // sdaのsmartを有効化
# smartctl -a /dev/sda // 全情報の表示
# smartctl -i /dev/sda // HDD識別情報の表示
テスト
# smartctl -t short -a /dev/sda
# smartctl -a /dev/sda // 出力中にテスト結果


#057 Scroll Lockキーの有効化


xmodmap -pmオプションで修飾キーのマップを確認
$ xmodmap -pm
空いてるところに、"Scroll_Lock"を割り当てる(e.g. mod3)
$ xmodmap -e 'add mod3 = Scroll_Lock'
キーを押し、LEDが点灯すればOK

※ xmodmapで、-pkとか-pkeとするとキーマップテーブルを表示

#058 lsでナチュラルソート

ファイル名の番号がゼロパディングされてない時とか。


$ ls -v
例えば、babelなどで。。
$ babel -ig03 `ls -v mol*.log` -omol2 all.ml2

#059 bcで関数定義


$ bc -ql
define f(x){ return 27.2116*x; }
または
define f(x)
{ return 27.2116*x; }
詳しくは、manページ

おまけ、Piを定義するには、arctan(i.e. radian=a(y/x))を使う。
例えば、
pi=a(1)*4
とか
pi=a(sqrt(3))*3


#060 awkで最終列を抽出


$0で行全体
NRは行数
NFはフィールド数
例えば、
$ awk '{print NR, NF;}' foo.txt
とすると行番号と各行のフィールド数が表示される。
それで、
$ awk '{print $NF;}' foo.txt
とすると最終列の値を抽出可能。

if文と組み合わせた例


#!/bin/bash

echo -e "E_homo[a.u]\t|E_homo|[eV]"
for file in `ls -v *.log`; do
grep -H "Alpha occ" $file | tail -n 1 | awk '{if ($NF<0) {print $NF, "\t", $NF*-27.2116} else {print $NF, "\t", $NF*27.2116} }'
done

exit



#061 Viのexモードで文字列を挿入

未着手。

Qキーでexモード、visualで通常モードへ


6〜10行を0行の下に移動
:6,10 m 05

11〜15行を行目の下にコピー
:11,15 co 5

16〜20行を削除
:16,20 d


#062 sshでホスト確認のyes/noを要求しない

${HOME}/.ssh/configに下記を追加


StrictHostKeyChecking=no


#063 password less ssh setting script

filename : set-nopass-ssh.sh ?


#!/bin/bash

echo Creating SSH key for ${USER}...

if [ -e ${HOME}/.ssh/id_rsa.pub ]; then
echo "${USER} already has a public key"
else
ssh-keygen -t rsa -N '' -f ${HOME}/.ssh/id_rsa
fi

echo Creating SSH config and authorized_keys for ${USER}...

if [ -e ${HOME}/.ssh/config ]; then
echo "backup for current config file"
cp ${HOME}/.ssh/config ${HOME}/.ssh/config.backup-$$
fi

echo "ServerAliveInterval 150" >> ${HOME}/.ssh/config
echo "StrictHostKeyChecking no" >> ${HOME}/.ssh/config
cat ${HOME}/.ssh/id_rsa.pub >> ${HOME}/.ssh/authorized_keys
chown ${USER}. ${HOME}/.ssh/authorized_keys
chmod 600 ${HOME}/.ssh/authorized_keys
chmod 600 ${HOME}/.ssh/config
ls -l ${HOME}/.ssh/

exit


#064 lessで制御文字を表示

-r または -R オプションを追加

scriptコマンドのログを表示する時などに便利。


#065 H/W情報の一括取得

$ lshw
-htmlや-xmlオプションで各形式で出力可能

#066 プロセスの作業ディレクトリを確認


/proc/PID/cwdをチェックしてもよいけど、pwdxコマンドってのがある。

$ pwdx プロセスID


#067 tty(昔のTeleTYpewriterの短縮)の確認

$ tty
仮想コンソール
/dev/tty1 - /dev/tty6 : text terminal
/dev/tty7 - /dev/tty63 : X Window System

※ Alt+Function-keyで切り替え可
※ X window起動中は、Ctrl+Alt+Function-keyで切り替え可
※ /dev/pts/0は、pseudo terminal(擬似端末)


#068 ldconfig コマンド

$ ldconfig
で/etc/ld.so.confに従い、/etc/ld.so.cacheを更新
$ ldconfig -p
でキャッシュ内容を表示


#069 last コマンド
オプション -i で、ホスト名をIPアドレスで表示。
オプション -x で、シャットダウン&ランレベル変更を表示

$ last -i
$ last -xi -n10


#070 manページのファイルを直接開く

manコマンドで、-l, --local-fileオプションを利用

$ man -l local-manfile


#071 tab補完の動作を変える



bashの場合、.bashrcなどで読み込まれる標準ファイルをコメントアウト

#if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
# . /etc/bash_completion
#fi

ホームディレクトリにコピー。
$ cp /etc/bash_completion ~/.bash_completion

適宜編集。

/etc/bash_completeを直接修正する場合。

(変更前)
# makeinfo and texi2dvi are defined elsewhere.
for i in a2ps awk bash bc bison cat colordiff cp csplit \
curl cut date df diff dir du enscript env expand fmt fold gperf gprof \
grep grub head indent irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
mv netstat nl nm objcopy objdump od paste patch pr ptx readelf rm rmdir \
sed seq sha{,1,224,256,384,512}sum shar sort split strip tac tail tee \
texindex touch tr uname unexpand uniq units vdir wc wget who; do
have $i && complete -F _longopt -o default $i
done

(変更後)
# makeinfo and texi2dvi are defined elsewhere.
for i in a2ps awk bash bc bison cat colordiff cp csplit \
curl cut date df diff dir du enscript env expand fmt fold gperf gprof \
grep grub head indent irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
mv netstat nl nm objcopy objdump od paste patch pr ptx readelf rm rmdir \
sed seq sha{,1,224,256,384,512}sum shar sort split strip tac tail tee \
texindex touch tr uname unexpand uniq units vdir wc wget who; do
have $i && complete -F _longopt -o filenames $i
done

~/.bash_completionを使用する場合

記述例1)
complete -F _longopt -o filenames ls
complete -F _longopt -o filenames cp

例2)
have()
{
unset -v have
# Completions for system administrator commands are installed as well in
# case completion is attempted via `sudo command ...'.
PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&
have="yes"
}

for i in a2ps awk bash bc bison cat colordiff cp csplit \
curl cut date df diff dir du enscript env expand fmt fold gperf gprof \
grep grub head indent irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
mv netstat nl nm objcopy objdump od paste patch pr ptx readelf rm rmdir \
sed seq sha{,1,224,256,384,512}sum shar sort split strip tac tail tee \
texindex touch tr uname unexpand uniq units vdir wc wget who; do
have $i && complete -F _longopt -o filenames $i
done
unset i

※ 上の例は、ubuntuでtab補完時に妙なスペースが入るようになったため、それの対処。。

設定内容は、次のようにして確認できる。

$ complete [-pr] | grep ls

※ complete はbashの組込みコマンドなので、manページは、man bashを確認。。


#072 awkで範囲抽出

ある文字列からある文字列まで(行)。


$ awk '/^DEF/,/MNO$/{print}' sample.txt

SDFである化合物のみを抽出。


$ awk '/^ZINC00000005/,/\$\$\$\$$/{print}' sample.sdf > extract.sdf


#073 メモリ使用量を調べる

timeの-vオプションでok。
出力中のMaximum resident set size (kbytes)を確認。


$ /usr/bin/time -v ls /

straceをつかえないかな?


#074 改行コードの置換のようなもの

sedだとうまくいかないので、awkのprintfを使う。


cat text.txt | awk '{printf $1 ", "}'


#075 ゼロパディング

printfをつかう。


$ for ( ( x=1;x< =20;x+=1 ) ); do echo `printf "%02d" $x`; done


#076 シェルで対話的に値を渡す

readを使う。


#!/bin/sh

/bin/echo -n "Yes/No ?: "
read str
echo $str

exit


#077 xargsの並列処理

bashで。


$ find . -name "*.tex" -type f | xargs -P4 -I {} -t latex {}
$ find . -name "*.dvi" -type f | time xargs -P4 -I {} -t dvipdf {} 2> stderr.P4.txt 1> stdout.P4.txt
$ find . -name "*.dvi" -type f | time xargs -I {} -t dvipdf {} 2> stderr.txt 1> stdout.txt
$ tail -n 2 stderr*.txt


#078 sshログイン時の"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!"の対処

ssh-keyscanでサーバー(接続先ホスト)のrsaキーを取得して、クライアント(接続元ホスト)の~/.ssh/known_hostsに追加する。sshの-Rオプションでport forwardingしている時などに、localhostrsaキーが変わり同様のエラーが。このような時は、ポートを指定して実行。


$ ssh-keyscan -p 16000 -t rsa localhost >> ~/.ssh/known_hosts


#079 time コマンドでelapsed timeをsec表示。


-f で出力形式を指定。詳細は、man time。以下、例。
$ /usr/bin/time -f "%C cmd %e real %U user %S sys %P CPU %M Max %I In %O Out %W swp %x status" sleep 1


#080 システム情報の取得

いろいろと便利なコマンド・ツールがあるー。


$ lsb_release -a
$ dmesg
$ lspci -vvv
$ lsusb -v
# lshw
# dmidecode
# sosreport
RedHat/CentOS系のみ
# smartctl --all /dev/sda

    • -

inxi
https://code.google.com/p/inxi/


#081 winmail.datを展開

tnefを使う。

http://sourceforge.net/projects/tnef/

実行するには、-fオプションでファイルを指定する。
$ tnef -f winmail.dat


#082 PDFの結合・分割

pdftkを使う。


結合
$ pdftk a.pdf b.pdf c.pdf cat output merged.pdf

分割
$ pdftk merged.pdf cat 4 output page4.pdf
$ pdftk merged.pdf cat 2-4 output page2-4.pdf
$ pdftk merged.pdf cat 2-4 8-end output page2-4_8-end.pdf


#083 viで行番号を追加, CSV変換のようなもの


:%!cat -n
で行番号を追加。タブ区切りをカンマに変える場合
:%s/\t/, /g
行頭のスペースを削除する場合、
:%s/^[ ]*//g
複数スペースをカンマにおきかえる場合、
:%s/\s\+/, /g


#084 dateの出力フォーマット

"+"で出力内容を指定。詳しくは、manページを。


$ date "+%Y%m%d"
20130610


#085 yumリポジトリをインストールDVDに変更

例、Scientific Linux 6.4のDVDメディア


1. /etc/yum.repo.d/以下に適当なrepoファイルを作成(dvd.repo)
内容は以下、ダブルクオーテーションやスペースは要バックスラッシュ。

[dvd]
name=Scientific Linux 6.4 DVD - $basearch
baseurl=file:///media/\"SL\ 6.4\ x86_64\ DVD1\"/

2. yumコマンドを実行
$ yum --disablerepo=\* --enablerepo=dvd search gnuplot


#086 一部の制御文字を非表示

screenやteeの出力を加工する際に便利。
cat, colコマンドを用いる。less -rみたいなところか。


$ cat typescript
$ col -bx < typescript


#087 標準エラー出力のハンドリング

/dev/stderrにリダイレクトした場合に、Permission deniedとなる場合。
(原因は、/dev/stderrのシンボリックリンク先の所有者・パーミッションが異なる等)

対処法


例えば、次のような場合
$ echo ERR >> /dev/stderr
/dev/stderr: Permission denied.

bashの場合
$ echo ERR 1>&2

cshの場合
$ echo ERR | perl -e "print stderr "

と書き換える。


#088 awkで偶数行/奇数行のみ出力


$ awk 'NR % 2 == 0' textfile
$ awk 'NR % 2 != 0' textfile


#089 サポートされるファイルシステムの確認


$ cat /proc/filesystems

モジュールについては、lsmod等で確認(e.g. iso9660)
$ lsmod | grep iso9660


#090 ISOファイルを直接マウント

  • o loopオプションを指定する。


# mount -t iso9660 -o loop file.iso /media/iso


#091 mpegアニメーションの作成


avconv使用(e.g. mov0001.png, moov0002.png, ..)
$ avconv -f image2 -i mov%04d.png movie.mpeg

Note: "%04d"はシェルのワイルドカードで置き換えられない。
printf()のようなフォーマット指定が必要


#092 viのmapあれこれ


15行毎に空行を挿入する(で挿入モードを抜ける)
:map S 15joS

2ワード先で改行を入れて複数カラムを単一カラムにする
:map K 2WjK

空白行の削除。※mapではないけども。
:v/\S/d

コマンドモードでEnterを押すと、空行が挿入される
:noremap o

メモ、
次のようにワードが切れていない場合、

  • 2.881842399053E-31-3.228892594097E-31

コマンドモードで、
:%s/-/ -/g
:%s/E -/E-/g
などとしてスペースを入れる。
その後、
:map K 1WjK
をマップ、実行して、
:v/\S/d
として空行を削除する、とよいかもしれない。

あれ、上でjとしているものはiじゃないかな。。
適当に書いてると駄目だorz
ロケールが問題な場合は、LANG=Cなどとしてリトライ。

a
b
c
l
m
n
x
y
z
といったデータを
a, b, c
l, m, n
x, y, z
に並べ替えるには
:map K j$a,J$a,JK


#093 sftp/scpのトンネル

比較的簡単。


$ ssh -fNL 15002:target-server:15001 -p 15000 duck@relay-server
$ scp -P 15002 file swan@localhost:/home/swan/
or
$ sftp -oPort=15002 localhost


#094 sudoのインタラクティブモード

知らなかったorz
ubuntu環境で便利なはず。


$ sudo -i


#095 mysqldumpによるバックアップとレストア

○バックアップ


myDB対象(文字コードUTF-8を指定)
$ mysqldump -u root -p password --default-character-set=utf8 myDB -r dump.sql

全DB対象
$ mysqldump -u root -p -x --all-databases > dump.sql

○レストア


myDB対象
$ mysql -u root -p myDB < dump.sql

全DB対象
$ mysql -u root -p < dump.sql

※ -pオプションでパスワードを省略すると入力を求められる。


#096 "-bash: fork: retry: リソースが一時的に利用できません"エラーの対処

上記エラーで何にも出来なくなった場合、シェルの組込みコマンドが使えるらしい。
例えば、execからsuを呼び出してリブートする。


$ exec su
パスワード入力
# reboot


#097 firewallでポートを開ける


/etc/sysconfig/iptablesを編集、"-A INPUT -j REJECT(略)"の上に

  • A INPUT -p tcp --dport 15000 -j ACCEPT -s "192.168.0.0/24"

のような一行を追加・保存し、デーモンを再起動する。

テンポラリに設定する場合、-A(append)ではなく、-I(insert)を使用して
ルールを追加する。ルール番号を省略すると一番上(1)に挿入される。

# iptables -I INPUT 5 -p tcp --dport 15000 -j ACCEPT

#098 gccでlibm.aをリンクできない

  • lmを最後に配置してみる。


例えば、
$ gcc -lm sample.o
"undefined reference to `exp'"のようなエラーが出る場合
$ gcc sample.o -lm
としてみる。


#099 ファイアウォールのルール設定

シンプルルール。。


# iptables -P INPUT ACCEPT
# iptables -F
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# iptables -P INPUT DROP
# iptables -P FORWARD DROP
# iptables -P OUTPUT ACCEPT
# iptables -L -v
と直接入力して、、
# /sbin/service iptables save
とすると、/etc/sysconfig/iptablesに設定ルールが保存される。

Ref.
http://wiki.centos.org/HowTos/Network/IPTables


#100 OpenGLバージョンの確認

glUseProgramは、v2.0以降対応。。


$ glxgears -info
$ glxinfo | grep OpenGL


#101 Qtでuicのバージョンが古い場合の対処法


"uic: File generated with too old version of"のようなエラーが出た場合。次のコマンドでコンバート。

$ uic3 -convert sample.ui


#102 w3m でフォーム&メタリロード


$ w3m -F -o meta_refresh=1 http://xxx
毎回のオプション指定が面倒な場合、~/.w3m/configに記述
例)
frame 1
meta_refresh 1
use_mouse 1
target_self 1
retry_http 1

その他のオプションを表示/確認するには、
$ w3m -show-option


#103 apacheログの解析

visitorsとgraphvizを使うとよさそう。


$ visitors -A -m 30 access.log > access.html
$ visitors access.log --prefix http://uhauha.net -V > graph.dot
$ dot -Tpng graph.dot > graph.png


#104 diffの-yオプションで表示カラム数を変える

  • W NUMオプションを使用する(デフォルトは130)。


$ diff -y -W 200 fileA fileB


#105 TCLLIBPATHの設定

コロンではなく、スペースでパスを分割する。


modulefileの例。
setenv TCLLIBPATH my/tcl8.5/itk3.4 my/tcl8.5/itcl3.4 my/tcl8.5/iwidgets4.0.2


#106 シェル変数に格納したtimeコマンドの実行

formatオプションを指定した場合のquotationが問題。evalで展開すればOK。


#!/bin/sh

TIME='/usr/bin/time -f "%C cmd %e real %U user %S sys %P CPU %M Max %I In %O Out %W swp %x status"'

eval ${TIME} date

#107 awkで重複カラムをまとめて表示

かなり便利。


2列目が重複する場合
$ awk '!a[$2]++' FILE
行全体
$ awk '!a[$0]++' FILE


#108 文字数順にソート

awkでlengthを出力してsortする。処理速度は遅いかもしれない。
セパレータはデータによって適宜変更。


$ awk -F "," '{print length,",",$0}' sample.txt | sort -n -r | awk -F "," '{print $2}' | cut -f2- -d' '


#109 debuginfo-install

デバッグ用にRPMパッケージを追加インストール。ワイルドカードも使えるらしいが。


例、カーネル
# debuginfo-install kernel
例、glibc
# debuginfo-install glibc-2.12-1.132.el6_5.4.x86_64 libgcc-4.4.7-11.el6.x86_64


#110 ファイルのフルパスを取得

例。


$ find `pwd` -maxdepth 1 -name "*.sdf"
or
$ ls -dF `pwd`/*


#111 パスワード付きzipファイル


zipコマンドで、-e or -encryptオプションを指定する。
$ zip -e output.zip input(s)
続けて、パスワード2回入力する。


#112 論理ボリュームのマウント


# fdisk -l
# lvdisplay (or pvscan, lvscan)
# lvchange --available y /dev/pv00/lv00
# mount /dev/mapper/pv00/lv00 /mnt
# umount /mnt


#113 ホストベース認証のパスワードレス ssh

クライアント側ホスト:/etc/ssh/ssh_config


Hostbasedauthentication yes
EnableSSHKeysign yes

サーバ側ホスト:/etc/ssh/sshd_config


Hostbasedauthentication yes
IgnoreRhosts no


#114 キャッシュにストアされているライブラリを表示

/etc/ld.so.cacheを見てるのかな。


$ /sbin/ldconfig -p

(※)LD_LIBRARY_PATH, LD_LIBRARY_PATH_64が面倒な場合、
/etc/ld.so.conf.d/にディレクトリを指定したany.confを作成し、
# /sbin/ldconfig
で反映してもいい。


#115 debパッケージを展開

dpkg-debコマンドを使用する。


$ dpkg-deb -x package.deb ./


#116 rpmの依存パッケージを確認


$ rpm -qp --requires abc.rpm


#117 GLベンチマーク

https://github.com/glmark2/glmark2


#118 文字列を含まないファイルを出力

"-L, --files-without-match"オプションを指定する。


$ grep -L string filename


#119 ubuntuでtar.gzの内容をリスト表示する

vimの方はzipでもOK


$ tar -tf file.tar.gz
or
$ vim file.tar.gz



#120 sedで指定フィールの置換

"\( \)"で括られたパターンを記憶し(最大9個/行?)、再利用する


$ echo '1234567890123456' | sed 's/\([^*]\)/X/9'
12345678X0123456
$ echo '1234567890123456' | sed 's/\([^*]\)/X/7'
123456X890123456


#121 7zipの使い方

高圧縮アーカイバ


インストール
$ apt-get install p7zip-full
圧縮
$ 7z a archive.7z directory/file
展開
$ 7z e archive.7z
内容確認
$ 7z l archive.7z


#122 bashキーバインドあれこれ


Ctrl+
L -> クリア
F -> カーソル右一文字移動
B -> カーソル左一文字移動
A -> 行頭へ移動
E -> 行末へ移動
D -> カーソル右一文字削除
H -> カーソル左一文字削除
K -> 行末まで削除
U -> 行頭まで削除
S -> Stop開始
Q -> Stop解除
W -> カーソル左一単語削除
P -> 前の履歴へ
N -> 次の履歴へ

Alt+
D -> カーソル右一単語削除

Esc+
F -> カーソル右一単語移動
B -> カーソル左一単語移動
U -> 末尾まで大文字に変更
L -> 末尾まで小文字に変更
C -> 右一文字大文字に変更

$ stty -a
もみてみると良い。

#123 awkのprint出力でフォーマットを変更する


manページより、
OFMT The output format for numbers, "%.6g", by default.

使用例
12桁表示(%.Ng)
$ echo "1 3" | awk '{OFMT="%.12g"} {print $1/$2}'
0.333333333333
科学表示(%.Ne)
$ echo "1 3" | awk '{OFMT="%.12e"} {print $1/$2}'
3.333333333333e-01
小数点表示(%.Nf)
$ echo "1 3" | awk '{OFMT="%.12f"} {print $1/$2}'
0.333333333333

"%.Ng"は、小数点表示が優先されるが指定桁数を越えた場合科学表示になる。

$ echo "2000000 3" | awk '{print $1/$2}'
666667
$ echo "20000000 3" | awk '{print $1/$2}'
6.66667e+06
$ echo "20000000 3" | awk '{OFMT="%.7g"}{print $1/$2}'
6666667

#124 テキストファイルを1行ずつ読み込む


cat filename | while read line
do
echo ${line}
done
もしくは、
while read line ; do
echo ${line}
done < filename

#125 xargsコマンド

標準入力をコマンド引数に変換する


$ ls -1 md*/*.tab | xargs -n1 grep -H Average


#126 sedである文字列からある文字列を削除


$ sed '/string1/,/string2/d' inp.txt > out.txt

Example.
$ cat inp.txt
I am not a animal.
I am not a bird.
I am a string1.
I am not a cat.
I am not a dog.
I am not a egg.
I am a string2.
I am not a giraff.
I am not a fragile.
$ sed '/string1/,/string2/d' inp.txt
I am not a animal.
I am not a bird.
I am not a giraff.
I am not a fragile.
$

#127 BoMの削除

Byte Order Markを消す。


$ sed -i -e '1s/^\xef\xbb\xbf//' file.txt
$ cat file.txt | awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}'
$ vim -b file.txt
としてバイナリモードで起動、を削除


#128 ファイルサイズが非ゼロのファイルを検索


$ find path -type f ! -size 0
改行なしリストを作成
$ find path -type f ! -size 0 | tr '\n' ' '


#129 aptコマンド

apt-get, apt-cacheは古いらしい。


パッケージ情報の更新 - apt update
パッケージの更新 - apt upgrade
パッケージの検索 - apt search
パッケージのインストール - apt install
パッケージの削除 - apt remove
パッケージの自動削除 - apt autoremove
パッケージの完全削除 - apt purge
パッケージキャッシュの削除 - apt clean
ローカルパッケージのインストール - apt install
インストール済みパッケージの一覧 - apt list --installed
全パッケージ一覧 - apt list
インストール済みパッケージ内のファイル一覧 - dpkg -L
パッケージ情報の表示 - apt show
パッケージの依存関係を表示 - apt depends
パッケージが依存されているパッケージを表示 - apt rdepends
ファイルを含むパッケージの検索 - dlocate

ref.
https://linuxfan.info/package-management-ubuntu


#130 ファイルがどのパッケージに含まれるか調べる


RHEL/CentOS
$ yum provides '*GL/gl.h'
または
$ yum whatprovides \*latex2html

Debian
apt-file未インストール時
$ sudo apt install apt-file
$ sudo apt-file update
その後
$ apt-file search 'GL/gl.h'


#131 rpmパッケージをダウンロード


$ yumdownloder pkgname


#132 pip/pip3コマンド


パッケージリスト表示
pip3 list
pip3 freeze
*freezeの場合、リストをインストール時に利用可

pip3 freeze > list.txt
pip3 install -r list.txt

更新状況確認(更新分のみ表示)
pip3 list --o
パッケージインストール
pip3 install pkgname
パッケージアップグレード
pip3 install pkgname -U
パッケージアンインストール
pip3 uninstall pkgname
プロキシ指定例
pip3 install pkgname --proxy=proxy-server-name
pip3のアップグレード
pip3 install --upgrade pip3