非常に詳細な2つのシェルコードの例
2022-01-07 02:34:57
非常に詳細な2つのシェル例
一般的なプログラミングの手順
では、スクリプトを書くための一般的な手順について説明します。どんな優れたスクリプトでも、ヘルプと入力パラメータを持つべきです。そして、ほとんどのスクリプトが必要とするフレームワーク構造を含む疑似スクリプト(framework.sh)を書くことは、非常に良いアイデアです。この時点で、新しいスクリプトを書くときは、copyコマンドを実行すればよいのです。
cp framework.sh myscript
次に、独自の関数を挿入します。
さらに2つの例を見てみましょう。
2進数から10進数への変換
b2dスクリプトは、2進数(例:1101)を対応する10進数に変換する。これは、expr コマンドを使った数学的操作の例でもある。
#! /bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat < b2h -- convert binary to decimal
USAGE: b2h [-h] binarynum
OPTIONS: -h help text
EXAMPLE: b2h 111010
will return 58
HELP
exit 0
error()
{
# print an error and exit
echo "$1"
exit 1
lastchar()
{
# return the last character of a string in $rval
if [ -z "$1" ]; then
# empty string
rval=""
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g'`
# now cut out the last char
rval=`echo -n "$1" | cut -b $numofchar`
}
chop()
{
# remove the last character in string and return it in $rval
if [ -z "$1" ]; then
# empty string
rval=""
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g'`
if [ "$numofchar" = "1" ]; then
# only one char in string
rval=""
return
fi
numofcharminus1=`expr $numofchar "-" 1`
# now cut all but the last char:
rval=`echo -n "$1" | cut -b 0-${numofcharminus1}`
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
--) shift;break;; # end of options
-*) error "error: no such option $1. -h for help";;
*) break;;
esac
done
# The main program
sum=0
weight=1
# one arg must be given:
[ -z "$1" ] && help
binnum="$1"
binnumorig="$1"
while [ -n "$binnum" ]; do
lastchar "$binnum"
if [ "$rval" = "1" ]; then
sum=`expr "$weight" "+" "$sum"`
fi
# remove the last position in $binnum
chop "$binnum"
binnum="$rval"
weight=`expr "$weight" "*" 2`
done
echo "binary $binnumorig is decimal $sum"
#
このスクリプトでは、10進数と2進数の重み(1,2,4,8,16,...)を利用したアルゴリズムを使用しています。例えば、2進数の "10" は、次のように10進数に変換できます。
0 * 1 + 1 * 2 = 2
1つの2進数を得るために、lastchar関数を使用しています。この関数は wc ?c を使って文字数を数え、cut コマンドを使って最後の文字を削除します;Chop 関数は最後の文字を削除します。
ファイルループプログラム
もしかしたら、送信したメールをすべてファイルに保存したいけれど、数ヶ月経つとファイルが大きくなってしまい、アクセス速度が遅くなってしまうという方もいらっしゃるのではないでしょうか。次のスクリプトrotatefileは、この問題を解決することができます。このスクリプトは、メール保存ファイル(outmailとする)の名前をoutmail.1に変更し、outmail.1に対してはoutmail.2、...といった具合に変更します。
#! /bin/sh
# vim: set sw=4 ts=4 et:
ver="0.1"
help()
{
cat < rotatefile -- rotate the file name
USAGE: rotatefile [-h] filename
OPTIONS: -h help text
EXAMPLE: rotatefile out
This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1
and create an empty out-file
The max number is 10
version $ver
HELP
exit 0
error()
{
echo "$1"
exit 1
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;;
--) break;;
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
# input check:
if [ -z "$1" ] ; then
error "ERROR: you must specify a file, use -h for help"
fi
filen="$1"
# rename any .1 , .2 etc file:
for n in Array 8 7 6 5 4 3 2 1; do
if [ -f "$filen.$n" ]; then
p=`expr $n + 1`
echo "mv $filen.$n $filen.$p"
mv $filen.$n $filen.$p
fi
done
# rename the original file:
if [ -f "$filen" ]; then
echo "mv $filen $filen.1"
mv $filen $filen.1
fi
echo touch $filen
touch $filen
このスクリプトはどのように動作するのでしょうか?ユーザーがファイル名を提供したことを検出した後、Array to 1ループを実行します。Arrayというファイルは10という名前になり、8というファイルはArrayという名前に変更される、といった具合です。ループが完了した後、元のファイルにFile 1という名前を付け、元のファイルと同じ名前の空のファイルを作成します。
デバッギング
最も簡単なデバッグコマンドは、もちろんechoコマンドを使うことです。echo を使えば、エラーがあると思われる場所に、どんな変数の値でも表示することができます。シェルプログラムの良さは、再コンパイルする必要がなく、echoコマンドを挿入しても、それほど時間がかからないことです。
また、シェルには本格的なデバッグモードがあります。もし、スクリプト "strangescript" にエラーがあれば、このようにデバッグすることができます。
sh -x strangescript
これにより、スクリプトが実行され、すべての変数の値が表示されます。
シェルには、スクリプトを実行せず、構文チェックのみを行うモードもあります。このように使うことができます。
sh -n your_script
これは、すべてのシンタックスエラーを返します。
これで、あなた独自のシェルスクリプトを書き始めることができ、楽しんでいただけると思います。
一般的なプログラミングの手順
では、スクリプトを書くための一般的な手順について説明します。どんな優れたスクリプトでも、ヘルプと入力パラメータを持つべきです。そして、ほとんどのスクリプトが必要とするフレームワーク構造を含む疑似スクリプト(framework.sh)を書くことは、非常に良いアイデアです。この時点で、新しいスクリプトを書くときは、copyコマンドを実行すればよいのです。
cp framework.sh myscript
次に、独自の関数を挿入します。
さらに2つの例を見てみましょう。
2進数から10進数への変換
b2dスクリプトは、2進数(例:1101)を対応する10進数に変換する。これは、expr コマンドを使った数学的操作の例でもある。
コピーコード
コードは以下の通りです。
#! /bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat < b2h -- convert binary to decimal
USAGE: b2h [-h] binarynum
OPTIONS: -h help text
EXAMPLE: b2h 111010
will return 58
HELP
exit 0
error()
{
# print an error and exit
echo "$1"
exit 1
lastchar()
{
# return the last character of a string in $rval
if [ -z "$1" ]; then
# empty string
rval=""
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g'`
# now cut out the last char
rval=`echo -n "$1" | cut -b $numofchar`
}
chop()
{
# remove the last character in string and return it in $rval
if [ -z "$1" ]; then
# empty string
rval=""
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g'`
if [ "$numofchar" = "1" ]; then
# only one char in string
rval=""
return
fi
numofcharminus1=`expr $numofchar "-" 1`
# now cut all but the last char:
rval=`echo -n "$1" | cut -b 0-${numofcharminus1}`
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
--) shift;break;; # end of options
-*) error "error: no such option $1. -h for help";;
*) break;;
esac
done
# The main program
sum=0
weight=1
# one arg must be given:
[ -z "$1" ] && help
binnum="$1"
binnumorig="$1"
while [ -n "$binnum" ]; do
lastchar "$binnum"
if [ "$rval" = "1" ]; then
sum=`expr "$weight" "+" "$sum"`
fi
# remove the last position in $binnum
chop "$binnum"
binnum="$rval"
weight=`expr "$weight" "*" 2`
done
echo "binary $binnumorig is decimal $sum"
#
このスクリプトでは、10進数と2進数の重み(1,2,4,8,16,...)を利用したアルゴリズムを使用しています。例えば、2進数の "10" は、次のように10進数に変換できます。
0 * 1 + 1 * 2 = 2
1つの2進数を得るために、lastchar関数を使用しています。この関数は wc ?c を使って文字数を数え、cut コマンドを使って最後の文字を削除します;Chop 関数は最後の文字を削除します。
ファイルループプログラム
もしかしたら、送信したメールをすべてファイルに保存したいけれど、数ヶ月経つとファイルが大きくなってしまい、アクセス速度が遅くなってしまうという方もいらっしゃるのではないでしょうか。次のスクリプトrotatefileは、この問題を解決することができます。このスクリプトは、メール保存ファイル(outmailとする)の名前をoutmail.1に変更し、outmail.1に対してはoutmail.2、...といった具合に変更します。
コピーコード
コードは以下の通りです。
#! /bin/sh
# vim: set sw=4 ts=4 et:
ver="0.1"
help()
{
cat < rotatefile -- rotate the file name
USAGE: rotatefile [-h] filename
OPTIONS: -h help text
EXAMPLE: rotatefile out
This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1
and create an empty out-file
The max number is 10
version $ver
HELP
exit 0
error()
{
echo "$1"
exit 1
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;;
--) break;;
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
# input check:
if [ -z "$1" ] ; then
error "ERROR: you must specify a file, use -h for help"
fi
filen="$1"
# rename any .1 , .2 etc file:
for n in Array 8 7 6 5 4 3 2 1; do
if [ -f "$filen.$n" ]; then
p=`expr $n + 1`
echo "mv $filen.$n $filen.$p"
mv $filen.$n $filen.$p
fi
done
# rename the original file:
if [ -f "$filen" ]; then
echo "mv $filen $filen.1"
mv $filen $filen.1
fi
echo touch $filen
touch $filen
このスクリプトはどのように動作するのでしょうか?ユーザーがファイル名を提供したことを検出した後、Array to 1ループを実行します。Arrayというファイルは10という名前になり、8というファイルはArrayという名前に変更される、といった具合です。ループが完了した後、元のファイルにFile 1という名前を付け、元のファイルと同じ名前の空のファイルを作成します。
デバッギング
最も簡単なデバッグコマンドは、もちろんechoコマンドを使うことです。echo を使えば、エラーがあると思われる場所に、どんな変数の値でも表示することができます。シェルプログラムの良さは、再コンパイルする必要がなく、echoコマンドを挿入しても、それほど時間がかからないことです。
また、シェルには本格的なデバッグモードがあります。もし、スクリプト "strangescript" にエラーがあれば、このようにデバッグすることができます。
sh -x strangescript
これにより、スクリプトが実行され、すべての変数の値が表示されます。
シェルには、スクリプトを実行せず、構文チェックのみを行うモードもあります。このように使うことができます。
sh -n your_script
これは、すべてのシンタックスエラーを返します。
これで、あなた独自のシェルスクリプトを書き始めることができ、楽しんでいただけると思います。
関連
-
[解決済み】C++使用時、代入の左オペランドにlvalueが必要なエラーについて
-
[解決済み】Looper.prepare()を呼び出していないスレッド内でハンドラを作成できない。)
-
[解決済み】ggplot2使用時の永続的な無効なグラフィックス状態エラー
-
[解決済み】浮動小数点例外(コアダンプ
-
[解決済み] テスト
-
[解決済み】IA-32 AT&T構文でのMOVZBL命令は何をするのですか?
-
[解決済み】Macでポート3000をロックしているプロセスを検索(およびkill)する
-
[解決済み】ヒストグラムが描けない、'x'は数値でなければならない
-
[解決済み】エラー:lvalueは単項演算子として必要です。
-
python startup prompt IDLEのサブプロセスが接続できない問題が発生しました。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
CSスクリプトの使用方法
-
InstallShield でレジストリキーを取得するスクリプト
-
[解決済み】入力文字列のフォーマットが正しくない
-
[解決済み] アクティブな例外なしで呼び出されたC++の終了
-
[解決済み】不正な文字列オフセットの警告 PHP
-
[解決済み】非静的メンバ関数の無効な使用 【重複あり
-
[解決済み】fatal error: Python.h: そのようなファイルやディレクトリはありません
-
[解決済み】この宣言は、C++でストレージクラスまたは型指定子を持っていない
-
[解決済み】PlayストアにAPKをアップロードする際に「com.exampleは制限されています。
-
linux シェル学習ノート 1日目