facebook twitter hatena line email

Linux/bashメモ

提供: 初心者エンジニアの簡易メモ
移動: 案内検索

シェル使い方

test.sh等の名前でパーティション:755で保存

bash test.shで実行可能

  1. !/bin/bashを頭につけると

test.shで動く

test.shで動かない場合は ./test.shとする

自分自信のパス

echo $(cd $(dirname $0);pwd)

変数割当はこうする

DIR=$(cd $(dirname $0);pwd)
echo "${DIR}"

phpスクリプトを動かす

cd /export1/batch/
/usr/local/bin/php test.php > log/test.log

2重起動防止

http://www.confrage.com/unix/sh/exe_dup/exe_dup.html

#!/bin/bash
if [ `ps ax | grep $0 | grep -v grep | wc -l` -gt 2 ]; then
    echo "Someone activating the $0 already."
    exit 1
fi

日付ログ

DATE=`date '+%Y/%m/%d %T'`
echo "$DATE start"                    >> log/test.log

日付ファイル

cp test.log test`date +"%Y%m%d"`.log

yesno問合せシェル

#!/bin/sh
function_yesno_query(){
    local yn_result=""
    while [ -z "$yn_result" ]; do
        read yn_reply
        case "$yn_reply" in
            [yY])
                yn_result=0;;
            [nN])
                yn_result=1;;
            *)
                echo "Please (y/n)";
        esac
    done
    return $yn_result
}
echo "Please (y/n)"
if function_yesno_query; then
    echo "yes"
else
    echo "no"
fi

サブルーチン

注意:returnは"数字"しか使えない

function subadd {
        #ローカル変数定義
        local one=1
        echo $1
        return `expr $2 + $3 + $one`
}
subadd "data1" 10 20
echo $?
subadd "data2" 5 15
echo $?

他サーバからファイル取得

#!/bin/sh
d="/home/admin1/test"
scp admin1@192.168.0.2:/home/admin1/config.ini $d"config.ini"

port指定

scp -P 3843 admin1@192.168.0.2:/home/admin1/config.ini $d"config.ini"

他のサーバーにファイル送信

# 通常
scp config.ini admin1@192.168.0.2:/home/admin1/config.ini
# sshkeyを追加して
scp -i secret_key.pem config.ini admin1@192.168.0.2:/home/admin1/config.ini
# dirをまとめて
scp -r application admin1@192.168.0.2:/home/admin1/

他サーバのバッチを叩く

#!/bin/sh
USER=admin1
TARGET_HOSTS="192.168.0.2"
PROG_PATH=/home/admin1/bin/batch1.php
SSH=/usr/bin/ssh
PHP=/usr/local/bin/php
for i in $TARGET_HOSTS; do
    $SSH $USER@$i $PHP $PROG_PATH
    echo "$SSH $USER@$i $PHP $PROG_PATH"
done;

サブバージョンexport

#!/bin/sh
cd /home/admin1/zend/master/system1
USER="userxxx"
PASS="xxxxxxx"
REPOSITORY="https://svn.xxxxxxxxxx/admin1/zend/system1/trunk/"
SVNEXPORT="svn export --username $USER --password $PASS"
# 複数指定はスペース区切り
TARGETS="system1"
LOG_FILE=/home/admin1/zend/logs/export/`date +%Y%m%d`.log
pushd .
cd /home/admin1/zend/master
#ディレクトリ削除
rm -fr /home/admin1/zend/master/system1
#export
for i in $TARGETS; do
  $SVNEXPORT --force ${REPOSITORY}${i} ${i} >> $LOG_FILE
done

svnからexport&rsync

rm -fr /tmp/project1
svn export svn+ssh://user1@example.com/var/svn/repos/project1 /tmp/project1
echo 'sabun'
SOURCE=/tmp/project1/
DEST=user1@example.com:/var/www/project1
rsync --dry-run -avuz --exclude '*.svn' --exclude=".DS_Store" --delete -e ssh $SOURCE $DEST | grep -v /$
echo 'deploy ok? (y/n'
read INDATA
if [ x"${INDATA}" != x"y" -a x"${INDATA}" != x"Y" ]; then
   echo "cancel."
   exit 1
fi
rsync -avuz --exclude '*.svn' --exclude=".DS_Store" --delete -e ssh $SOURCE $DEST |grep -v /$

linux/コマンドメモ/rsync [ショートカット]

他サーバのSmartyコンパイルファイルを削除

#!/bin/sh
USER=admin1
TARGET_HOSTS="192.168.0.2 192.168.0.3"
BASE_DIR=/var/www/html/zend/system1/application/views
SSH=/usr/bin/ssh
RM=/bin/rm
RM_OPT=-r
for i in $TARGET_HOSTS; do
    $SSH $USER@$i $RM $RM_OPT $BASE_DIR/caches/*
    echo "$SSH $USER@$i $RM $RM_OPT $BASE_DIR/caches/*"
    $SSH $USER@$i $RM $RM_OPT $BASE_DIR/compiles/*
    echo "$SSH $USER@$i $RM $RM_OPT $BASE_DIR/compiles/*"
done;

ログファイル操作

#30日以前のログ削除
0 2 * * *    find /tmp/log -name 'access_*.log.gz' -mtime +30 -exec rm -f {} \;
#前日ログ圧縮
0 3 * * *    find /tmp/log -name 'access_*.log' -mtime +1 -exec gzip {} \;

変数の範囲を指定

echo ${BASE_DIR}

ファイル内一括置換変更(grepreplace

grep hoge ./ -r -l|xargs sed s/hoge/fuga/g -i

変更ファイルトップ10

find ./ -name *.php | xargs ls -lt| head -10

if文法

if [ "a" != "b" ]; then
  echo "ng"
else
  echo "ok"
fi
if [ 10 -ne 9 ]; then

[]の前後にスペースを入れないと文法エラーとなる

文字の比較方法

if [ 1 != 2 ]
if [ 1 = 1 ]

数字の比較方法

if [ 1 -eq 2 ]  意味=
if [ 1 -ne 2 ]  意味!=
if [ 1 -gt 2 ]  意味>
if [ 1 -lt 2 ]  意味<
if [ 1 -ge 2 ]  意味>=
if [ 1 -le 2 ]  意味<=

空文字の比較

if [ -n "$test" ]; then

elseif

if [ "a" != "b" ]; then
  echo "ng"
elif [ "a" != "c" ]; then
  echo "ok"
else
  echo "ok"
fi

含まれる判定

hoge="abcdefg"
if [ "`echo $hoge | grep 'de'`" ]; then
  echo "含まれる"
fi

一括置換シェル

#!/bin/bash
function_yesno_query(){
    local yn_result="";
    while [ -z "$yn_result" ]; do
        read yn_reply
        case "$yn_reply" in
            [yY])
                yn_result=0;;
            [nN])
                yn_result=1;;
            *)
                echo "Please (y/n)";
        esac
    done
    return $yn_result
}
echo "grep list"
data1=aiueo
data2=kakikukeko
find . -name '*.txt' | xargs grep $data1
echo "dry replace ? (y/n)"
if function_yesno_query; then
  find . -name '*.txt' | xargs sed -e "s/$data1/$data2/g"
  echo "replace? (y/n)"
  if function_yesno_query; then
    find . -name '*.txt' | xargs sed -i -e "s/$data1/$data2/g"
      echo "ok"
  else
     echo "stop"
  fi
else
  echo "stop"

fi

ディレクトリがないとき判定

if [ ! -d /tmp/log ]
  mkdir /tmp/log
fi

パラメータに記載したファイル名が存在しないとき終了させる

bash test.sh sample.txt

vi test.sh

#!/bin/bash
[ -f $1 ] || exit 1

$1は${1}でも動作する

タグで囲まれた部分を削除

<!-- delete_flag -->で囲まれた部分を削除

vi sample.txt

aiueo
<!-- delete_flag -->
kakikukeko
sasisuseso
<!-- /delete_flag -->
abcd

vi del_tag.sh

#!/bin/bash
function sub_del_tag {
 #\r削除
 sed -i -e "s/\r//g" $1
 data=""
 viewflag=true
 while read line; do
   if [ "${line}" = "<!-- ${2} -->" ]; then
     viewflag=false
   fi
   if [ "${line}" = "<!-- /${2} -->" ]; then
     viewflag=true
     continue
   fi
   if [ $viewflag = true ]; then
     data="${data}${line}\n"
   fi
 done < $1
 echo ${data} > $1
}
sub_del_tag "sample.txt" "delete_flag"

正規表現マッチ

name=test.txt
if [[ "${name}" =~ \.(txt|php)$ ]]; then
  echo "file"
else
  echo "dir"
fi

ユーザ判定

if [ `whoami` != "admin" ]; then
echo "It is not admin user. Please run with admin user."
    exit
fi

bash実行時に環境変数を読み込む

sh実行時に~/.bash_profileを読み込んでるっぽいので普通に使える。

$ vi test.sh
#!/bin/bash
echo $ANDROID_HOME
$ test.sh
/Users/hogehoge/Library/Android/sdk

配列

,で区切らずspaceで区切る。=の両隣にspaceを入れないこと。

declare -a test_files=("test" "test2" "test3)
for e in ${test_files[@]}; do
    echo ${test_files[$i]}
    if [ -e ${test_files[$i]} ]; then
        echo ${test_files[$i]}
    fi
    let i++
done