bash をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
結構簡単なbashスクリプトを作っているが、細かい点を忘れが...
&size(10){もはやbashに関係ないものも書いているが..};
***ホスト毎に実行スクリプトを変更する [#hdbe1b0a]
#code(nonumber){{
[ -f /bin/hostname ] && host=`/bin/hostname -s`
case "$host" in
"em00"|"em01"|"em02")
source /home/Common/cpu.sh
;;
"g01"|"g02"|"g03")
source /home/Common/gpu.sh
;;
esac
unset host
}}
***cronでの多重起動防止 - pidof を使う [#vec6b673]
例えばrsyncの多重起動を防止したいとして下記のようにします.
#code(nonumber){{
[root@c ~]# cat backup_AtoB.bash
#!/bin/bash
/usr/bin/rsync -av --delete \
--log-file=/root/log/rsync-`date +"%Y%m%d%H%M%S"`.log \
/home root@destination:/backup/home/
[root@c ~]# crontab -e
MAILTO=""
0 23 * * * /usr/sbin/pidof -x backup_AtoB.bash >/dev/nu...
[root@c ~]#
}}
説明としてはスクリプト「backup_AtoB.bash」プロセス番号を...
「||」で繋いでいるので、前段(/usr/sbin/pidof -x backup_At...
前段の失敗とはそのようなプロセスがない. つまりは「backup_...
「backup_AtoB.bash」プロセスが存在していれば、「||」の後...
スクリプト名で判断するので同じ名前のスクリプトが走ってい...
***cronでの多重起動防止 - touch を使う [#l810f7e7]
もっと簡単な転送方法としては下記スクリプトを cron に噛ま...
#code(nonumber){{
#!/bin/bash
# mount先を確認するなら. (リモート越しのrsyncなら不要)
if [ ! -f "/OffloadData/_offloaddata_" ]; then
exit
fi
# 実行中確認ファイルを確認して
if [ -f "/root/script/run" ]; then
exit
else
touch /root/script/run
fi
# tiffファイルの転送なら
/usr/bin/rsync -av --delete --include="*/" --include="*.t...
/OffloadData/ /ceph/OffloadData/ \
--log-file=/root/script/log/rsync-`date +%Y%m%d-%H%M`....
# ssh でアクセス可能なフォルダで所有者、パーミッションを...
/usr/bin/rsync -rltDvog --chown=cryoem:cryoem --chmod=F64...
access-user@camera:/CameraServer/ /ceph/CameraServer/ \
--exclude '@Recycle' --exclude '.@__thumb' --ignore-e...
--log-file=/root/script/log/rsync-`date +%Y%m%d-%H%M`....
/bin/rm -f /root/script/run
}}
***parallel [#x2a7f710]
&color(white,blue){注意};
CentOSにはパッケージ[moreutils-parallel.x86_64]と[paralle...
■[moreutils-parallel.x86_64]なら
#code(nonumber){{
parallel [option] [実行コマンド] -- [引数(変数かな?)]
例:
[saber@c Movies]$ parallel -j3 -i relion_convert_to_tiff ...
-jはパラレル数
-iは引数の結果を{}で代用する
}}
■[parallel.noarch](通称「GNU Parallel」)なら
#code(nonumber){{
(--dry-runで確認)
[saber@c Movies]$ ls *.mrc | parallel --dry-run relion_co...
(実行)
[saber@c Movies]$ ls *.mrc | parallel relion_convert_to_t...
}}
「-j」で同時実行数を決められるが、何も指定しないとthreads...
***8には注意 [#e07ec029]
#code(nonumber){{
a="0008"
echo $(($c))
}}
を実行すると「行 2: 0008: 基底の値が大きすぎます (エラー...
#code(nonumber){{
a="0008"
echo $((10#$c))
}}
と修正すればok
***ファイルの存在が確認できたら実行する [#uac9ae7a]
前段での処理が完了して、その出力ファイルの存在を確認した...
#code(nonumber){{
until [ -r Micrographs/$seqfile ] ; do sleep 1; done
}}
***findで見つけたファイルをtarで固める [#qbe4e528]
#code(nonumber){{
tar . -name \( '*.html' -o -name '*.htm' \) -print0 | ta...
}}
***繰り返して実行する [#ff29081c]
#code(nonumber){{
while true ;do echo `date '+%y%m%d %H%M%S'` $(sensors | h...
while true; do echo `date '+%y%m%d %H:%M:%S'` $(smartctl...
}}
***pidに関係するファイルをみる [#u6ab1dc0]
#code(nonumber){{
lsof -p <pid>
watch -n 2 lsof -p <pid> <-- 2秒ごとにlsofの内容を表...
}}
***○行目以降を表示 [#qe043658]
qstatの表示で上二行を省いて表示
#code(nonumber){{
qstat | tail -n +3
}}
***ヒアドキュメント [#z3050ec6]
#code(nonumber){{
cat << _EOF_ > README.1st
どうして
こうなった?
_EOF_
}}
変数に収めるなら
#code(nonumber){{
l=$(cat <<_EOF_
どうしても
こうなる
_EOF_
) #改行して「)」を入れる
}}
***awk [#j1584250]
awkをbashで使ったので
unixユーザで、uidが1000以上のユーザリストを取得する
#code(nonumber){{
[foo@c ~]$ getent passwd |awk -F: '$3>1000{print $1}'
}}
「-F」はデミリタ、「$3」でUIDの部分を示してそれが1000より...
***標準出力 [#y14c8556]
標準出力、標準エラー共に一つのファイルに入れる. 「&color(...
#code(nonumber){{
[foo@c ~]$ ./bash.cmd > log 2>&1
}}
&size(10){他にも「./bash.cmd &color(crimson){>&}; log」...
共に出力しないなら「&color(magenta){2>1&};」と「&color(me...
#code(nonumber){{
[foo@c ~]$ ./bash.cmd > /dev/null 2>&1
}}
どちらとも別々のファイルに入れたい. log1(標準出力)、log2(...
#code(nonumber){{
[foo@c ~]$ ./bash.cmd 1> log1 2> log2
}}
標準エラーは画面に出しつつファイルにも書いて欲しい。標準...
&color(magenta){tee};コマンドは標準出力をファイルに落とし...
なので一旦エラーの識別子(2)を(1)に変更して、パイプ(|)で渡す
#code(nonumber){{
[foo@c ~]$ { ./bash.cmd 3>&2 2>&1 1>&3 | tee log1; } ...
}}
&color(white,blue){留意}; 先頭の「&color(red){''{''};」の...
「3>&2 2>&1 1>&3」の考え方だけど、1と2を入れ替えただ...
&ref(2017y08m23d_190145715.png,nolink); 最終的に1と2が...
***for文 [#i4cebc24]
よく使います. フォルダ内のファイルを処理したい場合
#code(nonumber){{
#!/bin/bash
IFS=$'\n' # IFS="$'\n'$'\t' " デフォルト値...
for f in `ls /tmp`; do
echo $f
done
}}
そのフォルダが複数ある場合
#code(nonumber){{
#!/bin/bash
etc=`ls -d /etc/*` #/etc直下のファイルをフルパスで...
tmp=`ls -d /tmp/*` #同/tmp直下も
for f in $etc $tmp; do # 2つの変数を同時に扱う
echo $f
done
}}
特定のファイルで
#code(nonumber){{
#!/bin/bash
mrcs=$(find /data4 -type f -name "*.mrcs" | grep -e "[0-9...
for f in $mrcs; do
echo $f
done
}}
連番のファイルにしたい
#code(nonumber){{
#!/bin/bash
mrcs=$(find /data4 -type f -name "*.mrcs")
i=1
for f in $mrcs; do
cmd="ln -s $f $(printf "%04d" $i).mrcs" #一旦コマンド...
$cmd
i=$(expr $i + 1)
done
}}
既に連番を持ったファイルで偶数番号のファイルだけを拾いたい
#code(nonumber){{
#!/bin/bash
tif=$(find . -name "*.tif")
i=1
for f in $tif; do #aaaa
num=$(echo $f | cut -c6-9|bc) # ファイル名の連番部分...
if [ $(($num%2)) == 0 ]; then # 2で割った余りで偶数/...
echo $f
fi
done
}}
***for文 一行で [#i38c4710]
#code(nonumber){{
for i in `ls *.tif`; do echo $i ;done
}}
一分ごとにコマンドを実行
#code(nonumber){{
for i in `ls *.tif`;do echo $i; cp $i /xxx/xxx/Micrograph...
}}
***超簡易並列 [#k1c6d70e]
多数のディレクトリに対して処理を施したいが、どうせなら複...
っで作ってみた
#code(nonumber,nooutline,nolink){{
#!/bin/bash
cat <<'_EOF_'>run.$$.sh # 個々のディレクトリで...
#!/bin/bash
echo start:`date '+%y%m%d %H:%M:%S'`
expr `cat max |bc` - 1 > max
<目的の処理>
expr `cat max |bc` + 1 > max
echo end:`date '+%y%m%d %H:%M:%S'`
_EOF_
chmod +x run.$$.sh
echo 8 > max. # 同時実行数
for d in `find . -maxdepth 2 -mindepth 2 -type d`; do ...
./run.$$.sh $d & # 「&」でバックグラウンド...
sync # 「max」ファイルの同期に...
if [ $(expr `cat max`) -eq 0 ]; then
while :
do
sleep 10
echo "break:" `cat max`
if [ $(expr `cat max`) -gt 0 ]; then
break
fi
done
fi
done
rm -f run.$$.sh max
}}
***文字列操作 [#me528a5d]
#code(nonumber){{
pid=12345.chaperone.jp
echo ${pid%%.*} ---> 12345
echo ${pid%.*} ---> 12345.chaperone
echo ${pid#*.} ---> chaperone.jp
echo ${pid##*.} ---> jp
#-------------------------------#
dir="/var/lib/pbs"
echo ${dir##*/} ---> pbs *注意 dir="/var...
echo ${dir#*/} ---> var/torque/pbs
echo ${dir%/*} ---> /var/torque *注意 dir="/var...
echo ${dir%%/*} ---> "" (なし)
#-------------------------------#
tif="Micrographs/s1_100001_movie.tif"
echo ${tif/_movie.tif}.mrc --> Micrographs/s1_100001.mrc
}}
***空行とコメント行(#)を取り除くには [#d431690f]
#code(nonumber){{
[root@c ~]# sed '/^#/d' /etc/chrony.conf | sed '/^$/d'
server ntp.nict.jp iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
[root@c ~]#
}}
***マシン同士のバックアップ [#f6108dc4]
方法はたくさんある。
rsync, rsnapshot, lsync,,
簡単に
#code(nonumber){{
#!/bin/bash
#
log=backup.log
#
d=$(date +%y%m%d_%H%M%S)
#
if [ -f runfile ];then
echo "This backup script is already running ($d)"
exit
else
/bin/cat <<_EOF_>runfile
start: $d
_EOF_
cmd="rsync -avz -delete --log-file=/var/log/rsync-`date +...
--log-file-format=\"%o %f (%U %B) %l %b\" /home/ root@ba...
$cmd
/bin/rm -f runfile
fi
}}
***容量確認 [#bb4fc947]
&color(red){みかんせい};
#code(nonumber){{
d=$(/usr/bin/df -l -t xfs -h | /usr/bin/grep data| /usr/b...
for i in $d ;do
find $i -mindepth 1 -maxdepth 1 -type d -exec du -hs {...
don
}}
終了行:
結構簡単なbashスクリプトを作っているが、細かい点を忘れが...
&size(10){もはやbashに関係ないものも書いているが..};
***ホスト毎に実行スクリプトを変更する [#hdbe1b0a]
#code(nonumber){{
[ -f /bin/hostname ] && host=`/bin/hostname -s`
case "$host" in
"em00"|"em01"|"em02")
source /home/Common/cpu.sh
;;
"g01"|"g02"|"g03")
source /home/Common/gpu.sh
;;
esac
unset host
}}
***cronでの多重起動防止 - pidof を使う [#vec6b673]
例えばrsyncの多重起動を防止したいとして下記のようにします.
#code(nonumber){{
[root@c ~]# cat backup_AtoB.bash
#!/bin/bash
/usr/bin/rsync -av --delete \
--log-file=/root/log/rsync-`date +"%Y%m%d%H%M%S"`.log \
/home root@destination:/backup/home/
[root@c ~]# crontab -e
MAILTO=""
0 23 * * * /usr/sbin/pidof -x backup_AtoB.bash >/dev/nu...
[root@c ~]#
}}
説明としてはスクリプト「backup_AtoB.bash」プロセス番号を...
「||」で繋いでいるので、前段(/usr/sbin/pidof -x backup_At...
前段の失敗とはそのようなプロセスがない. つまりは「backup_...
「backup_AtoB.bash」プロセスが存在していれば、「||」の後...
スクリプト名で判断するので同じ名前のスクリプトが走ってい...
***cronでの多重起動防止 - touch を使う [#l810f7e7]
もっと簡単な転送方法としては下記スクリプトを cron に噛ま...
#code(nonumber){{
#!/bin/bash
# mount先を確認するなら. (リモート越しのrsyncなら不要)
if [ ! -f "/OffloadData/_offloaddata_" ]; then
exit
fi
# 実行中確認ファイルを確認して
if [ -f "/root/script/run" ]; then
exit
else
touch /root/script/run
fi
# tiffファイルの転送なら
/usr/bin/rsync -av --delete --include="*/" --include="*.t...
/OffloadData/ /ceph/OffloadData/ \
--log-file=/root/script/log/rsync-`date +%Y%m%d-%H%M`....
# ssh でアクセス可能なフォルダで所有者、パーミッションを...
/usr/bin/rsync -rltDvog --chown=cryoem:cryoem --chmod=F64...
access-user@camera:/CameraServer/ /ceph/CameraServer/ \
--exclude '@Recycle' --exclude '.@__thumb' --ignore-e...
--log-file=/root/script/log/rsync-`date +%Y%m%d-%H%M`....
/bin/rm -f /root/script/run
}}
***parallel [#x2a7f710]
&color(white,blue){注意};
CentOSにはパッケージ[moreutils-parallel.x86_64]と[paralle...
■[moreutils-parallel.x86_64]なら
#code(nonumber){{
parallel [option] [実行コマンド] -- [引数(変数かな?)]
例:
[saber@c Movies]$ parallel -j3 -i relion_convert_to_tiff ...
-jはパラレル数
-iは引数の結果を{}で代用する
}}
■[parallel.noarch](通称「GNU Parallel」)なら
#code(nonumber){{
(--dry-runで確認)
[saber@c Movies]$ ls *.mrc | parallel --dry-run relion_co...
(実行)
[saber@c Movies]$ ls *.mrc | parallel relion_convert_to_t...
}}
「-j」で同時実行数を決められるが、何も指定しないとthreads...
***8には注意 [#e07ec029]
#code(nonumber){{
a="0008"
echo $(($c))
}}
を実行すると「行 2: 0008: 基底の値が大きすぎます (エラー...
#code(nonumber){{
a="0008"
echo $((10#$c))
}}
と修正すればok
***ファイルの存在が確認できたら実行する [#uac9ae7a]
前段での処理が完了して、その出力ファイルの存在を確認した...
#code(nonumber){{
until [ -r Micrographs/$seqfile ] ; do sleep 1; done
}}
***findで見つけたファイルをtarで固める [#qbe4e528]
#code(nonumber){{
tar . -name \( '*.html' -o -name '*.htm' \) -print0 | ta...
}}
***繰り返して実行する [#ff29081c]
#code(nonumber){{
while true ;do echo `date '+%y%m%d %H%M%S'` $(sensors | h...
while true; do echo `date '+%y%m%d %H:%M:%S'` $(smartctl...
}}
***pidに関係するファイルをみる [#u6ab1dc0]
#code(nonumber){{
lsof -p <pid>
watch -n 2 lsof -p <pid> <-- 2秒ごとにlsofの内容を表...
}}
***○行目以降を表示 [#qe043658]
qstatの表示で上二行を省いて表示
#code(nonumber){{
qstat | tail -n +3
}}
***ヒアドキュメント [#z3050ec6]
#code(nonumber){{
cat << _EOF_ > README.1st
どうして
こうなった?
_EOF_
}}
変数に収めるなら
#code(nonumber){{
l=$(cat <<_EOF_
どうしても
こうなる
_EOF_
) #改行して「)」を入れる
}}
***awk [#j1584250]
awkをbashで使ったので
unixユーザで、uidが1000以上のユーザリストを取得する
#code(nonumber){{
[foo@c ~]$ getent passwd |awk -F: '$3>1000{print $1}'
}}
「-F」はデミリタ、「$3」でUIDの部分を示してそれが1000より...
***標準出力 [#y14c8556]
標準出力、標準エラー共に一つのファイルに入れる. 「&color(...
#code(nonumber){{
[foo@c ~]$ ./bash.cmd > log 2>&1
}}
&size(10){他にも「./bash.cmd &color(crimson){>&}; log」...
共に出力しないなら「&color(magenta){2>1&};」と「&color(me...
#code(nonumber){{
[foo@c ~]$ ./bash.cmd > /dev/null 2>&1
}}
どちらとも別々のファイルに入れたい. log1(標準出力)、log2(...
#code(nonumber){{
[foo@c ~]$ ./bash.cmd 1> log1 2> log2
}}
標準エラーは画面に出しつつファイルにも書いて欲しい。標準...
&color(magenta){tee};コマンドは標準出力をファイルに落とし...
なので一旦エラーの識別子(2)を(1)に変更して、パイプ(|)で渡す
#code(nonumber){{
[foo@c ~]$ { ./bash.cmd 3>&2 2>&1 1>&3 | tee log1; } ...
}}
&color(white,blue){留意}; 先頭の「&color(red){''{''};」の...
「3>&2 2>&1 1>&3」の考え方だけど、1と2を入れ替えただ...
&ref(2017y08m23d_190145715.png,nolink); 最終的に1と2が...
***for文 [#i4cebc24]
よく使います. フォルダ内のファイルを処理したい場合
#code(nonumber){{
#!/bin/bash
IFS=$'\n' # IFS="$'\n'$'\t' " デフォルト値...
for f in `ls /tmp`; do
echo $f
done
}}
そのフォルダが複数ある場合
#code(nonumber){{
#!/bin/bash
etc=`ls -d /etc/*` #/etc直下のファイルをフルパスで...
tmp=`ls -d /tmp/*` #同/tmp直下も
for f in $etc $tmp; do # 2つの変数を同時に扱う
echo $f
done
}}
特定のファイルで
#code(nonumber){{
#!/bin/bash
mrcs=$(find /data4 -type f -name "*.mrcs" | grep -e "[0-9...
for f in $mrcs; do
echo $f
done
}}
連番のファイルにしたい
#code(nonumber){{
#!/bin/bash
mrcs=$(find /data4 -type f -name "*.mrcs")
i=1
for f in $mrcs; do
cmd="ln -s $f $(printf "%04d" $i).mrcs" #一旦コマンド...
$cmd
i=$(expr $i + 1)
done
}}
既に連番を持ったファイルで偶数番号のファイルだけを拾いたい
#code(nonumber){{
#!/bin/bash
tif=$(find . -name "*.tif")
i=1
for f in $tif; do #aaaa
num=$(echo $f | cut -c6-9|bc) # ファイル名の連番部分...
if [ $(($num%2)) == 0 ]; then # 2で割った余りで偶数/...
echo $f
fi
done
}}
***for文 一行で [#i38c4710]
#code(nonumber){{
for i in `ls *.tif`; do echo $i ;done
}}
一分ごとにコマンドを実行
#code(nonumber){{
for i in `ls *.tif`;do echo $i; cp $i /xxx/xxx/Micrograph...
}}
***超簡易並列 [#k1c6d70e]
多数のディレクトリに対して処理を施したいが、どうせなら複...
っで作ってみた
#code(nonumber,nooutline,nolink){{
#!/bin/bash
cat <<'_EOF_'>run.$$.sh # 個々のディレクトリで...
#!/bin/bash
echo start:`date '+%y%m%d %H:%M:%S'`
expr `cat max |bc` - 1 > max
<目的の処理>
expr `cat max |bc` + 1 > max
echo end:`date '+%y%m%d %H:%M:%S'`
_EOF_
chmod +x run.$$.sh
echo 8 > max. # 同時実行数
for d in `find . -maxdepth 2 -mindepth 2 -type d`; do ...
./run.$$.sh $d & # 「&」でバックグラウンド...
sync # 「max」ファイルの同期に...
if [ $(expr `cat max`) -eq 0 ]; then
while :
do
sleep 10
echo "break:" `cat max`
if [ $(expr `cat max`) -gt 0 ]; then
break
fi
done
fi
done
rm -f run.$$.sh max
}}
***文字列操作 [#me528a5d]
#code(nonumber){{
pid=12345.chaperone.jp
echo ${pid%%.*} ---> 12345
echo ${pid%.*} ---> 12345.chaperone
echo ${pid#*.} ---> chaperone.jp
echo ${pid##*.} ---> jp
#-------------------------------#
dir="/var/lib/pbs"
echo ${dir##*/} ---> pbs *注意 dir="/var...
echo ${dir#*/} ---> var/torque/pbs
echo ${dir%/*} ---> /var/torque *注意 dir="/var...
echo ${dir%%/*} ---> "" (なし)
#-------------------------------#
tif="Micrographs/s1_100001_movie.tif"
echo ${tif/_movie.tif}.mrc --> Micrographs/s1_100001.mrc
}}
***空行とコメント行(#)を取り除くには [#d431690f]
#code(nonumber){{
[root@c ~]# sed '/^#/d' /etc/chrony.conf | sed '/^$/d'
server ntp.nict.jp iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
[root@c ~]#
}}
***マシン同士のバックアップ [#f6108dc4]
方法はたくさんある。
rsync, rsnapshot, lsync,,
簡単に
#code(nonumber){{
#!/bin/bash
#
log=backup.log
#
d=$(date +%y%m%d_%H%M%S)
#
if [ -f runfile ];then
echo "This backup script is already running ($d)"
exit
else
/bin/cat <<_EOF_>runfile
start: $d
_EOF_
cmd="rsync -avz -delete --log-file=/var/log/rsync-`date +...
--log-file-format=\"%o %f (%U %B) %l %b\" /home/ root@ba...
$cmd
/bin/rm -f runfile
fi
}}
***容量確認 [#bb4fc947]
&color(red){みかんせい};
#code(nonumber){{
d=$(/usr/bin/df -l -t xfs -h | /usr/bin/grep data| /usr/b...
for i in $d ;do
find $i -mindepth 1 -maxdepth 1 -type d -exec du -hs {...
don
}}
ページ名:
1