シェルスクリプトの学習
1. シェルとは何ですか?
1. シェルの概要
シェルは、ユーザーがオペレーティング システムと対話し、さまざまなタスクや操作を実行できるようにするコンピューター オペレーティング システムのコマンド ライン インターフェイス (CLI) です。シェルは、ユーザーがタスクを自動化し、一連のコマンドを実行するスクリプトを作成できるようにするスクリプト プログラミング言語でもあります。
Linux および Unix オペレーティング システムでは、Shell 是用户与操作系统内核之间的中间层
ユーザーが入力したコマンドを受け入れ、これらのコマンドを実行のためにカーネルに渡します。ユーザーがキーボードからコマンドを入力すると、シェルが解释和执行
これらのコマンドをシェル化します。シェルは処理输入和输出、环境变量、文件操作
なども担当します。
一般的なシェルには、Bash (Bourne-Again シェル)、Zsh (Z シェル)、Fish (Friendly Interactive Shell) などが含まれます。各シェルには独自の特性と機能があります。Bash は、Linux および macOS で最も一般的なデフォルトのシェルです
シェルの主な用途は次のとおりです。
- コマンドとプログラムの実行: ユーザーはシェルにコマンドを入力して、プログラムの実行、ファイルの管理、システム ステータスの表示などを行うことができます。
- スクリプト プログラミング: ユーザーはシェル スクリプトを記述して、一連のコマンドと操作を組み合わせて自動タスクを実現できます。
- パイプとリダイレクト: シェルを使用すると、ユーザーはコマンドの出力を他のコマンドにパイプしたり、入出力をファイルやデバイスにリダイレクトしたりできます。
- 環境変数管理: シェルを使用すると、ユーザーは、ユーザーとプログラムの実行環境に影響を与える環境変数を設定および管理できます。
- プロセス制御: シェルは条件付きステートメント、ループ、分岐をサポートし、ユーザーが複雑なスクリプト ロジックを作成できるようにします。
2. 貝殻の分類
JavaScript や PHP プログラミングと同様、シェル プログラミングには、コードを作成できるテキスト エディターと、それを解釈して実行できるスクリプト インタプリタが必要です。Linux には多くの種類のシェルがあり、一般的なものは次のとおりです。
- ボーン シェル (/usr/bin/sh または /bin/sh)
- ボーン・アゲイン シェル(/bin/bash)
- Cシェル(/usr/bin/csh)
- Kシェル(/usr/bin/ksh)
- ルート用シェル(/sbin/sh)
このチュートリアルでは、Bourne Again Shell としても知られる Bash に焦点を当てています。Bash は使いやすく無料であるため、日常業務で広く使用されています。同時に、Bash はほとんどの Linux システムのデフォルトのシェルでもあります。
一般に、人々はボーン シェルとボーン アゲイン シェルを区別しません。#!/bin/sh同样也可以改为 #!/bin/bash
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序
3. 最初のシェルスクリプト
# 1. vim helloworld.sh 是打开一个文本编辑器(Vim)并创建或打开名为 "helloworld.sh" 的文件的命令
vim helloworld.sh
# 2. echo "hello, world!" 是一个 Shell 命令。作用是在终端上打印 "hello, world!"
echo "hello,world!"
# 3. 用于为一个文件赋予可执行权限
chmod +x helloworld.sh
# 4. 运行这个脚本的命令
./helloworld.sh
- 実行効果は以下の通りです。
4. 複数のコマンドの実行
複数のコマンド実行者 | 効果 | フォーマット |
---|---|---|
; | 複数のコマンドは、コマンド間の論理的な接続なしで順番に実行されます。 | コマンド 1; コマンド 2 |
&& | コマンド 1 が正しく実行された場合 (終了ステータス コードが 0)、コマンド 2 が実行され、そうでない場合はコマンド 2 は実行されません。 | コマンド 1 && コマンド 2 |
|| | コマンド 2 は、コマンド 1 が正しく実行されなかった場合 (終了ステータス コードが 0 でない場合) にのみ実行され、それ以外の場合はコマンド 2 は実行されません。 | コマンド 1 || コマンド 2 |
複数のコマンドの実行例:
-
セミコロン (;) は複数のコマンドを順番に実行するために使用され、コマンド間に論理的な接続はありません。
$ command1 ; command2 ; command3
例:
$ ls ; echo "Hello" ; date
ls
上記のコマンドは、コマンド (現在のディレクトリの内容を一覧表示)、echo
コマンド (「Hello」を表示)、およびdate
コマンド (現在の日付と時刻を表示)を実行します。 -
論理 AND (&&) 演算子は、前のコマンドが正しく実行された場合にのみ、次のコマンドを実行するために使用されます。
$ command1 && command2
例:
$ rm file.txt && echo "File deleted successfully"
上記のコマンドは、まず
file.txt
ファイルの削除を試み、削除に成功したらecho
コマンドを実行して「ファイルは正常に削除されました」と表示します。ファイルの削除に失敗した場合(コマンド 1 が正しく実行されなかった場合)、echo
コマンドは実行されません。 -
論理 OR (||) 演算子は、前のコマンドが正しく実行されなかった場合にのみ、次のコマンドを実行するために使用されます。
$ command1 || command2
例:
$ find /tmp -name "file.txt" || echo "File not found"
上記のコマンドは、まず
/tmp
ディレクトリ内で「file.txt」という名前のファイルを検索しようとします。ファイルが見つかった場合 (コマンド 1 が正しく実行された場合)、echo
コマンドは実行されません。ファイルが見つからない場合(コマンド 1 の実行が間違っている場合)、echo
コマンドが実行され、「ファイルが見つかりません」と表示されます。
2. シェル変数
3.1 変数の命名規則
シェル スクリプトでは、変数はデータの保存と操作に使用される重要な要素です。変数に適切な名前を付けることは、明確で読みやすい、堅牢なスクリプトを作成するための鍵となります。シェル変数の命名規則は次のとおりです。
-
変数名には次のものを含めることができます。
- 文字 (大文字または小文字): a ~ z または A ~ Z。
- 数値: 0 ~ 9 (ただし、変数名を数字で始めることはできません)。
- 下線を引きます
_
。
-
変数名は文字またはアンダースコアで始める必要があります。数字で始めることはできません。
-
変数名では大文字と小文字が区別されるため、
$myVar
と は$myvar
2 つの異なる変数です。 -
シェルの予約キーワード (if、while、for など) を変数名として使用しないでください。
-
スクリプトの読みやすさを向上させるために、意味のある説明的な変数名を使用することをお勧めします。
-
一般的な命名スタイル:
-
キャメルケース: 最初の単語は小文字で始まり、後続の単語の最初の文字は大文字になります。
例:myVariableName
、thisIsCamelCase
。 -
アンダースコアの命名法 (スネークケース): すべての文字は小文字であり、単語は
_
アンダースコアで区切られます。
例:my_variable_name
、this_is_snake_case
。
-
例:
以下に、さまざまな変数の命名規則を示す例をいくつか示します。
# 驼峰命名法示例
myVariableName="Hello, World!"
thisIsCamelCase="这是一个驼峰命名"
anotherCamelCaseVariable="这是另个驼峰命名"
# 下划线命名法示例
my_variable_name="Hello, World!"
this_is_snake_case="这是下划线命名"
another_snake_case_variable="这是另一个下划线命名"
正しい変数命名規則はシェル スクリプト プログラミングの基礎の 1 つであり、保守しやすく読みやすいコードを作成し、エラーを減らし、コードの品質を向上させるのに役立ちます。
3.2 変数の特殊記号
-
$ : ドル記号は変数の値を参照するために使用されます。
例:myVar="Hello" echo $myVar # 输出:Hello
-
* : アスタリスクのワイルドカード。0 個以上の文字と一致するために使用されます。
例:ls *.txt # 列出所有以 ".txt" 结尾的文件
-
? : 疑問符ワイルドカード。任意の文字と一致するために使用されます。
例:ls file?.txt # 列出类似 "file1.txt"、"fileA.txt" 的文件
-
[ ] : 角括弧は文字セットを定義するために使用され、角括弧内の任意の文字と一致します。
例:ls [aeiou]* # 列出以元音字母开头的文件
-
{ } : 中かっこは、コマンド シーケンスの作成または文字列の展開に使用されます。
例:echo { A,B,C} # 输出:A B C
-
| : 垂直バーは、あるコマンドの出力を別のコマンドに渡してパイプを形成するために使用されます。
例:cat file.txt | grep "pattern" # 在文件中搜索模式
-
; : セミコロンは複数のコマンドを区切るために使用され、複数のコマンドを 1 行で実行できます。
例:command1; command2 # 依次执行两个命令
-
&& : 論理 AND 演算子。2 つのコマンドを実行し、最初のコマンドが成功した後にのみ 2 番目のコマンドを実行するために使用されます。
例:make && make install # 如果 make 成功,则执行 make install
-
|| : 2 つのコマンドを実行し、最初のコマンドが失敗した場合にのみ 2 番目のコマンドを実行するために使用される論理 OR 演算子。
例:command1 || echo "command1 failed" # 如果 command1 失败,则输出提示
-
\> : 大なり記号は、コマンドの出力をファイルにリダイレクトするために使用されます。
例:echo "Hello, World!" > output.txt # 将文本写入文件
- >> : 二重大なり記号は、コマンドの出力をファイルに追加するために使用されます。
例:
echo "More text" >> output.txt # 追加文本到文件
- < : 小なり記号は、ファイルの内容をコマンドへの入力としてリダイレクトするために使用されます。
例:
command < input.txt # 使用文件内容作为输入执行命令
- ` : バックティックはコマンドを実行し、文字列として出力するために使用されます。
例:
currentDate=`date` # 获取当前日期并存储为字符串
3.3 ユーザー定義変数
変数はシェル スクリプト作成者によって定義され、特定のタスクまたは計算の中間結果を保存するために使用されます。スコープは現在のシェル プロセスまたはスクリプトです。
1. 変数を定義します。
シェル スクリプトでは、等号 (=) を使用して変数を定義できます。变量名不应该包含空格,并且通常使用大写字母
、システム環境変数と区別するために。
myVar="Hello, World"
2. 変数を割り当てます。
変数に値を代入するには、代入演算に等号 (=) を使用するだけです。
myVar="New Value"
3. 変数を使用します。
変数の値を使用するには、変数の前にドル記号 ($) を付けます。
echo $myVar
4. 文字列の連結:
変数は文字列と連結できます。
greeting="Hello"
name="John"
echo "$greeting, $name!"
例:
[root@localhost shell]# NAME="cxk"
[root@localhost shell]# DOING="play-basketball"
[root@localhost shell]# echo $NAME $DOING
cxk play-basketball
[root@localhost shell]# echo "$NAME,$DOING!!!"
cxk,play-basketball!!!
5. 変数をエクスポートします。
変数を現在のシェルの環境にエクスポートして、他の子プロセスもアクセスできるようにする場合は、export
コマンドを使用できます。
export myVar="Exported Value"
6. 読み取り専用変数:
変数を読み取り専用にして、値が変更されないようにすることができます。
readonly myVar="This variable is read-only"
例:
[root@localhost shell]# var='cxk'
[root@localhost shell]# echo $var
cxk
[root@localhost shell]# var='rap'
[root@localhost shell]# echo $var
rap
[root@localhost shell]# readonly var='ikun'
[root@localhost shell]# echo $var
ikun
[root@localhost shell]# var='cxk'
-bash: var: 只读变量
7. 変数を削除します。
unset
変数はコマンドを使用して削除できます。
unset myVar
例:
[root@localhost shell]# setVar='temp'
[root@localhost shell]# echo $setVar
temp
[root@localhost shell]# unset setVar
[root@localhost shell]# echo $setVar
8. ベストプラクティス:
- コードの読みやすさを向上させるために、意味のある変数名を使用してください。
- スペースまたは特殊文字を含む文字列を処理するには、二重引用符を使用して変数を引用します。
- システム環境変数との競合を避けるため、非環境変数を定義する場合はすべて大文字を使用しないでください。
- 変数を使用する前に、予期しないエラーを避けるために変数が定義されているかどうかを確認してください。
readonly
変更すべきではない変数が誤って変更されるのを防ぐために使用します。export
変数を子プロセスで使用できるようにするために使用します。- コードの保守性を向上させるために、変数の目的を説明するコメントを追加します。
3.4 環境変数
1. 環境変数とは何ですか?
環境変数は、オペレーティング システム レベルで保存されるキーと値のペアであり、構成情報、パス、ユーザー設定などを保存するために使用されます。シェル環境変数は、システムの動作を制御および構成するために非常に重要です
2. 環境変数を確認します。
コマンドとドル記号 ($)を使用してecho
、特定の環境変数の値を表示します
。たとえば、現在のユーザーのホーム ディレクトリ パスを出力します。
echo $HOME
3. 環境変数を設定します。
export
環境変数を設定するには、次のコマンドを使用できます。
export MY_VARIABLE="Hello"
これにより、という名前の環境変数が作成されMY_VARIABLE
、その値が「Hello」に設定されます。この変数は現在のシェル セッション内で使用できることに注意してください。
4. 永続的な環境変数:
環境変数を永続的にするには、通常、環境変数をシェル構成ファイル(Bash シェルの場合は.bashrc
または など) に追加します。.bash_profile
このようにして、新しいシェル セッションが開始されるたびに変数が自動的に設定されます。
5. すべての環境変数を表示します。
env
定義されているすべての環境変数を表示するには、次のコマンドを使用できます。
env
または、printenv
次のコマンドを使用します。
printenv
6. 環境変数を削除します。
unset
環境変数を削除するには、次のコマンドを使用できます。
unset MY_VARIABLE
7. 環境変数を使用します。
環境変数はスクリプトで非常に役立ち、構成情報やパスを保存するために使用できます。次に例を示します。
# 使用环境变量
echo "home路径的环境变量地址: $HOME"
8. システムの事前定義環境変数:
オペレーティング システムとシェルは、システム情報や構成にアクセスするために使用できるPATH
、HOME
、などのいくつかの環境変数を事前定義します。USER
9. 環境変数をインポートします。
環境変数をインポートするとは、環境変数を外部ファイルまたはソースから現在のシェル セッションにロードして、現在のセッションで使用できるようにすることを意味します。通常、ファイルから構成情報をロードしたり、環境変数を設定したり、他のスクリプトを実行したりする前に、必要な環境変数が定義されていることを確認するために使用されます。
シェルでは、環境変数をインポートする方法がいくつかあります。
-
source
コマンドまたは(ドット)を使用.
:これら 2 つのコマンドは、指定されたファイル内のコマンドを実行し、結果を現在のシェル セッションに適用するために使用されます。通常は、 などの環境変数ファイルをロードするために使用されます.env
。source .env # 或者 . .env
ここで、 は
.env
環境変数定義を含むファイルです。これらのコマンドを実行すると、.env
ファイルに定義された環境変数が現在のシェル セッションで有効になります。 -
コマンドの使用
export
:export
環境変数を現在のシェル セッションにインポートし、子プロセスで使用できるようにする場合は、次のコマンドを使用できます。export MY_VARIABLE="Hello"
これにより、現在のシェル セッションに名前付きの環境変数が作成され
MY_VARIABLE
、現在のセッションとその子プロセスで使用できるようになります。 -
Pass
~/.bashrc
または~/.bash_profile
:新しい Bash シェル セッションを開始するたびに環境変数を自動的にインポートする場合は、ユーザーのホーム ディレクトリの.bashrc
またはファイルに環境変数を追加できます。.bash_profile
こうすることで、ログインするたびに環境変数が自動的に設定されます。たとえば、
.bashrc
次の行をファイルに追加して環境変数をインポートできます。source /path/to/myenvfile
10. ベストプラクティス:
- コードの読みやすさを向上させるために、意味のある変数名を使用してください。
- 不要な問題を避けるために、システムの事前定義された環境変数を上書きしないでください。
- 機密情報 (パスワードなど) が必要な場合は、環境変数に保存することは避けてください。これは、環境変数は通常、情報を保存する安全な方法ではないためです。
3.5 位置パラメータ変数
- これらの変数は、シェル スクリプトでコマンド ライン引数を取得するために使用されます。
$0
スクリプトの名前を示し、$1
最初のパラメータを示し、$2
2 番目のパラメータを示します。- 例:
script.sh arg1 arg2 # 在脚本内部可以使用 $0、$1、$2 获取参数
3.6 事前定義された変数
- シェルには、シェルとシステムに関する情報を取得するための特別な事前定義変数がいくつか用意されています。
- たとえば、
$HOME
現在のユーザーのホーム ディレクトリや$PWD
現在の作業ディレクトリを表します。 - 例:
echo "当前用户的主目录是 $HOME"
3.7 キーボード入力を受け入れる
- これらの変数は、ユーザーからのキーボード入力を受け入れるために使用されます。
- たとえば、
read
コマンドは、ユーザー入力を指定された変数に保存するために使用されます。 - 例:
echo "请输入您的姓名:" read userName echo "您输入的姓名是:$userName"
3. シェルオペレーター
以下は、シェル スクリプトの一般的な演算子の構文と例です。
オペレーターの種類 | オペレーター | 構文例 | 例 |
---|---|---|---|
算術演算子 | 追加 | result=$((a + b)) |
5 + 2 結果は7 |
引き算 | result=$((a - b)) |
5 - 2 結果は3 |
|
乗算 | result=$((a * b)) |
5 * 2 結果は10 |
|
分割 | result=$((a / b)) |
10 / 3 結果は3 |
|
残りを取る | result=$((a % b)) |
15 % 7 結果は1 |
|
関係演算子 | 等しい | [ "$a" -eq "$b" ] |
5 -eq 5 それは本当です |
等しくない | [ "$a" -ne "$b" ] |
5 -ne 2 それは本当です |
|
以上 | [ "$a" -gt "$b" ] |
5 -gt 2 それは本当です |
|
未満 | [ "$a" -lt "$b" ] |
5 -lt 10 それは本当です |
|
以上 | [ "$a" -ge "$b" ] |
5 -ge 5 それは本当です |
|
以下 | [ "$a" -le "$b" ] |
5 -le 10 それは本当です |
|
論理演算子 | AND演算 | [ "$a" -gt 0 ] && [ "$a" -lt 10 ] |
5 > 0 そして5 < 10 それは本当です |
OR演算 | [ "$a" -eq 0 ] || [ "$a" -eq 10 ] |
5 = 0 または5 = 10 偽です |
|
操作ではありません | ! [ "$a" -eq 5 ] |
5 = 5 偽です |
|
代入演算子 | 割り当て | x=10 |
x 等しい10 |
加算的な代入 | x=$((x + 5)) |
x 加算5 後はx 等しい15 |
|
減算代入 | y=$((y - 5)) |
y マイナス5 にy 等しい15 |
|
ビット演算子 | ビットごとの AND | result=$((a & b)) |
5 & 3 結果は1 |
ビットごとの OR | result=$((a | b)) |
5 | 3 結果は7 |
|
ビットごとの XOR | result=$((a ^ b)) |
5 ^ 3 結果は6 |
|
ビット単位の否定 | result=$((~a)) |
~5 結果は-6 |
|
左方移動 | result=$((a << 2)) |
5 << 2 結果は20 |
|
右シフト | result=$((a >> 1)) |
5 >> 1 結果は2 |
3.1 算術演算子
注: シェルで変数a
との加算演算を実行する場合b
、それを実現するには特定の構文を使用する必要があります。直接入力しても、$a+$b
シェルはそれを見つからないコマンドとして扱うため、シェルでは追加操作として解釈されません。
expr
加算演算を実行するには、コマンドまたは式を使用できます$((...))
。両方の方法の例を次に示します。
-
方法 1:
expr
コマンドを使用するa=1 b=2 result=$(expr $a + $b) echo "a + b = $result"
-
方法 2:
$((...))
式を使用するa=1 b=2 result=$((a + b)) echo "a + b = $result"
数学的演算を実行するために使用されます。サポートされている算術演算子は+
、、、、、、です。-
*
/
%
# 语法:result=$((expression))
a=5
b=2
# 加法
result=$((a + b)) # 结果是7
# 减法
result=$((a - b)) # 结果是3
# 乘法
result=$((a * b)) # 结果是10
# 除法
result=$((a / b)) # 结果是2
# 取余
result=$((a % b)) # 结果是1
3.2 関係演算子
2 つの値間の関係を比較するために使用されます。サポートされている関係演算子は-eq
、、、、、、、です。-ne
-gt
-lt
-ge
-le
# 语法:[ expression ]
# 注意:方括号内的空格是必需的!
a=5
b=10
# 相等
if [ "$a" -eq "$b" ]; then
echo "$a 等于 $b"
else
echo "$a 不等于 $b"
fi
# 不等于
if [ "$a" -ne "$b" ]; then
echo "$a 不等于 $b"
else
echo "$a 等于 $b"
fi
# 大于
if [ "$a" -gt "$b" ]; then
echo "$a 大于 $b"
else
echo "$a 不大于 $b"
fi
# 小于
if [ "$a" -lt "$b" ]; then
echo "$a 小于 $b"
else
echo "$a 不小于 $b"
fi
# 大于等于
if [ "$a" -ge "$b" ]; then
echo "$a 大于等于 $b"
else
echo "$a 小于 $b"
fi
# 小于等于
if [ "$a" -le "$b" ]; then
echo "$a 小于等于 $b"
else
echo "$a 大于 $b"
fi
3.3 論理演算子
論理演算を実行するために使用されます。サポートされている論理演算子は&&
、(論理 AND)、||
(論理 OR)、!
(論理 NOT) です。
# 语法:command1 && command2
# command2 仅在 command1 返回真(退出状态码为0)时执行
# 与运算
if [ "$a" -gt 0 ] && [ "$a" -lt 10 ]; then
echo "$a 大于0并且小于10"
else
echo "$a 不满足条件"
fi
# 或运算
if [ "$a" -eq 0 ] || [ "$a" -eq 10 ]; then
echo "$a 等于0或等于10"
else
echo "$a 不满足条件"
fi
# 非运算
if ! [ "$a" -eq 5 ]; then
echo "$a 不等于5"
else
echo "$a 等于5"
fi
3.4 代入演算子
変数に値を代入するために使用されます。サポートされている代入演算子は=``+=
、、、、、、です。-=
*=
/=
%=
# 语法:variable operator expression
x=10
y=20
# 赋值
x=5
y=10
# 加法并赋值
x=$((x + 5)) # x 现在等于10
# 减法并赋值
y=$((y - 5)) # y 现在等于15
3.5ビット演算子
ビット演算を実行するために使用されます。サポートされているビット演算子は&
、(ビットごとの AND)、|
(ビットごとの OR)、^
(ビットごとの排他的 OR)、(ビットごとの~
否定) <<
、(左シフト)、>>
(右シフト) です。
# 语法:result=$((expression))
a=5
b=3
# 按位与
result=$((a & b)) # 结果是1
# 按位或
result=$((a | b)) # 结果是7
# 按位异或
result=$((a ^ b)) # 结果是6
# 按位取反
result=$((~a)) # 结果是-6
# 左移
result=$((a << 2)) # 结果是20
# 右移
result=$((a >> 1)) # 结果是2
4. プロセス制御
シェルスクリプトのプロセス制御構造には、条件文(if文)、ループ文(forループ、whileループ)、case文などが含まれます。以下に、各フロー制御構造の詳細な構文と使用例を示します。
4.1 条件文 - if 文
-
if
ステートメントは、特定の条件下でさまざまなコマンドを実行するために使用されます。構文は次のとおりです。if [ condition ]; then # 条件为真时执行的命令 else # 条件为假时执行的命令 fi
-
例:
#!/bin/bash x=10 if [ $x -eq 10 ]; then echo "x 等于 10" else echo "x 不等于 10" fi
4.2 ループ文 - for ループ
-
for
ループは、リスト内の要素に対して一連のコマンドを実行するために使用されます。構文は次のとおりです。for variable in list; do # 在每次迭代中执行的命令 done
-
例:
#!/bin/bash fruits=("apple" "banana" "cherry") for fruit in "${fruits[@]}"; do echo "水果:$fruit" done
4.3 ループ文 - while ループ
-
while
ループは、条件が true の場合、条件が false になるまで一連のコマンドを実行するために使用されます。構文は次のとおりです。while [ condition ]; do # 当条件为真时执行的命令 done
-
例:
#!/bin/bash count=1 while [ $count -le 5 ]; do echo "循环次数:$count" ((count++)) done
4.4 ケースステートメント
-
case
ステートメントは、さまざまな条件に基づいてさまざまなコマンドを実行するために使用されます。構文は次のとおりです。case expression in pattern1) # 匹配 pattern1 时执行的命令 ;; pattern2) # 匹配 pattern2 时执行的命令 ;; *) # 默认情况下执行的命令 ;; esac
-
例:
#!/bin/bash fruit="apple" case $fruit in "apple") echo "这是苹果" ;; "banana") echo "这是香蕉" ;; *) echo "这不是苹果或香蕉" ;; esac
4.5 制御フロー - 中断して続行
-
break
ループを終了するために使用されます。 -
continue
現在のループの残りの部分をスキップし、次の反復を続行するために使用されます。 -
例:
#!/bin/bash for i in { 1..5}; do if [ $i -eq 3 ]; then continue fi echo "循环次数:$i" if [ $i -eq 4 ]; then break fi done
5.機能
シェル関数は、特定のタスクや計算を実行するために一連のコマンドとロジックを再利用可能なユニットにカプセル化できる強力なツールです。この記事では、シェル関数の構文を詳しく掘り下げ、シェル関数をよりよく理解して使用するための複数の実践的な例を示します。
5.1 シェル関数の定義
シェル関数は、キーワードを使用するものとコンパクト形式を使用するものという 2 つの異なる構文形式を使用できますfunction
。
5.1.1 関数キーワード関数定義
function function_name {
# 函数体,包括命令和逻辑
# 可以接受参数
# 可以使用局部变量
# 可以返回一个值
}
5.1.2 コンパクト形式の関数定義
function_name() {
# 函数体
}
5.2 関数呼び出し
関数を定義すると、スクリプト内の必要な場所でその関数を呼び出すことができます。関数を呼び出すときは、その名前の後に必要な引数を指定するだけです。
文法:
function_name argument1 argument2
簡単な関数呼び出しの例
# 定义一个函数,用于打印欢迎消息
welcome() {
echo "欢迎来到Shell函数示例!"
}
# 调用函数
welcome
5.3 関数パラメータ
関数はパラメーターを受け入れることができるため、関数の多用途性と柔軟性が高まります。関数内では、 、 などの変数を使用して、関数$1
に渡されるパラメーターを参照できます。これらの変数は、最初のパラメーター、2 番目のパラメーター、3 番目のパラメーターなどを表します。$2
$3
パラメーターを受け入れる関数の例を見てみましょう。
# 定义一个函数,接受两个参数并打印它们
print_arguments() {
echo "第一个参数: $1"
echo "第二个参数: $2"
}
# 调用函数,并传递两个参数
print_arguments "Hello" "World"
print(){
echo "你的名字:$1"
echo "你的爱好:$2"
}
print "蔡徐坤" "打篮球"
5.4 関数の戻り値
シェル関数は値を返すことができるため、関数は計算を実行し、結果をメイン プログラムに返すことができます。値を返すには、return
ステートメントを使用し、それをメイン プログラムで使用して$?
戻り値を取得します。
2 つの数値の合計を計算し、結果を返す関数の例:
# 定义一个函数,计算两个数字之和并返回结果
add_numbers() {
local sum=$(( $1 + $2 ))
return $sum
}
# 调用函数,并获取返回值
add_numbers 5 7
result=$?
echo "5 + 7 的和是:$result"
5.5 ローカル変数
シェル関数では、local
キーワードを使用してローカル変数を作成できます。ローカル変数は関数内でのみ表示され、グローバル スコープ内の変数には影響しません。これは、コードの他の部分との競合を気にせずに関数内で変数を使用できるため、非常に便利です。
ローカル変数の関数例:
# 定义一个函数,演示局部变量
my_function() {
local local_variable="局部变量"
echo "在函数内部:$local_variable"
}
local_variable="全局变量"
my_function
echo "在函数外部:$local_variable"
fun(){
echo "全局变量值:$var"
local var="局部变量"
echo "局部变量赋值后:$var"
}
var="全局变量"
fun
5.6 実践例
5.6.1 階乗の計算
指定された数値の階乗を計算します。階乗は、正の整数と 1 からその整数までのすべての正の整数の積です。
# 定义一个函数,计算给定数字的阶乘
calculate_factorial() {
local number=$1
local result=1
if [ $number -lt 0 ]; then
echo "输入必须是非负整数。"
return 1
fi
for (( i=1; i<=number; i++ )); do
result=$((result * i))
done
echo "$number 的阶乘是:$result"
return 0
}
# 调用函数,计算阶乘
calculate_factorial 5
calculate_factorial 0
calculate_factorial -3
5.6.2 ファイルの検索
ファイル システム内で特定のファイルを検索し、そのファイルへのパスを返します。
# 定义一个函数,查找文件并返回路径
find_file() {
# 接受两个参数:文件名和搜索目录
local file_name=$1
local search_dir=$2
# 检查是否提供了有效的文件名和搜索目录
if [ -z "$file_name" ] || [ -z "$search_dir" ]; then
echo "请输入文件名和搜索目录。"
return 1 # 返回错误代码1表示参数不足或无效
fi
# 使用`find`命令在指定目录中查找文件
local result=$(find "$search_dir" -name "$file_name")
# 检查是否找到文件
if [ -z "$result" ]; then
echo "未找到文件 '$file_name'。"
return 1 # 返回错误代码1表示未找到文件
else
echo "文件 '$file_name' 的路径是:$result"
return 0 # 返回成功代码0表示找到文件
fi
}
# 调用函数,查找文件
find_file "example.txt" "/path/to/search" # 查找存在的文件
find_file "missing.txt" "/path/to/search" # 查找不存在的文件
find_file "" "/path/to/search" # 无效的参数:文件名为空
6. 文字のインターセプト、置換、および処理コマンド
6.1 共通の文字処理
6.1.1 文字列の長さ
文法:
${
#string}
例:
string="Hello, World!"
length=${
#string}
echo "字符串的长度为:$length" # 输出 "字符串的长度为:13"
6.1.2 部分文字列のインターセプト
文法:
${string:起始位置:长度}
例:
string="Hello, World!"
substring="${string:0:5}" # 从位置0开始截取5个字符
echo "$substring" # 输出 "Hello"
6.1.3 プレフィックスの削除
文法:
${string#前缀}
例:
string="/path/to/file.txt"
without_prefix="${string#/path/}" # 删除前缀 "/path/"
echo "$without_prefix" # 输出 "to/file.txt"
6.1.4 サフィックスの削除
文法:
${string%后缀}
例:
string="/path/to/file.txt"
without_suffix="${string%.txt}" # 删除后缀 ".txt"
echo "$without_suffix" # 输出 "/path/to/file"
6.1.5 小文字への変換
文法:
${string,,}
例:
string="Hello, World!"
lowercase="${string,,}" # 转换为小写
echo "小写: $lowercase" # 输出 "小写: hello, world!"
6.1.6 大文字への変換
文法:
${string^^}
例:
string="Hello, World!"
uppercase="${string^^}" # 转换为大写
echo "大写: $uppercase" # 输出 "大写: HELLO, WORLD!"
6.1.7 文字列置換(最初の一致)
文法:
${string/要替换的子串/替换为的字符串}
例:
string="姓名:name,age:20,height:159cm,艺名:name"
replaced="${string/name/cxk}" # 替换第一个 "name" 为 "cxk"
echo "$replaced" # 输出 "姓名:cxk,age:20,height:159cm,艺名:name"
6.1.8 文字列置換(すべて一致)
文法:
${string//要替换的子串/替换为的字符串}
例:
string="姓名:name,age:20,height:159cm,艺名:name"
replaced="${string//name/cxk}" # 替换所有的 "apples" 为 "bananas"
echo "$replaced" # 输出 "I love bananas, bananas are great!"
6.1.9 部分文字列一致の抽出
文法:
[[ $string =~ 正则表达式 ]]
匹配结果:${
BASH_REMATCH[n]}
例:
string="我的邮箱 [email protected]"
# 使用正则表达式来匹配字符串中的邮箱地址,并将匹配结果存储在`BASH_REMATCH`数组中,然后提取出匹配的邮箱地
if [[ $string =~ [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{
2,4} ]]; then
email="${
BASH_REMATCH[0]}"
echo "匹配到的邮箱地址是:$email"
fi
6.2 正規表現とワイルドカード
6.2.1 正規表現とワイルドカードの違い
-
正規表現:
- 正規表現は、
模式匹配
パターンに基づいてテキスト内の文字列を照合するための強力なツールです。これは包含一致であるため、文字列内のどこにでも一致します。 grep
Linux では、 、などのコマンドは通常、正規表現をサポートawk
しsed
ています。正規表現を使用して、テキストの検索、置換、フィルタリングなどを行うことができます。- 正規表現の豊富な構文を使用すると、キャプチャ、グループ化、繰り返し一致などの高度なテキスト操作を実行できます。
例:
- 数値を含むすべての行を検索するために使用します
grep
。grep '[0-9]' file.txt
- 正規表現は、
-
ワイルドカード:
- ファイル名を一致させるにはワイルドカードが使用されます。これは、ファイルの内容に関係なく、特定のパターンに一致するファイル名のみと一致する完全一致です。
ls
Linux では、 、などのコマンドは通常find
、cp
ワイルドカードをサポートしています。ワイルドカード文字は、ファイル内のテキストではなく、ファイルの検索または操作に使用されます。- ワイルドカード文字には
*
、(0 個以上の文字に一致)、?
(1 文字に一致)、[...]
(文字範囲に一致) などが含まれます。
例:
- で終わる
ls
すべてのファイルをリストするために使用します:.txt
ls *.txt
要約:
- 正規表現はテキスト処理に使用され、より高度なマッチングと操作をサポートします。
- ワイルドカードはファイル名の照合に使用され、基本的なファイル選択ツールです。
6.2.2 一般的に使用される正規表現
正規表現パターン | 説明する | 使用例 |
---|---|---|
^pattern |
で始まる行と一致しますpattern 。 |
grep '^Error' file.txt 「Error」で始まる行に一致します。 |
pattern$ |
で終わる行と一致しますpattern 。 |
grep 'end$' file.txt 「end」で終わる行と一致します。 |
. |
改行を除く任意の 1 文字と一致します。 | grep 'a.b' file.txt 「aab」、「axb」などに一致します。 |
* |
前の文字または部分式の 0 個以上のインスタンスと一致します。 | grep 'go*gle' file.txt 「ggle」、「google」、「google」などに一致します。 |
+ |
前の文字または部分式の 1 つ以上のインスタンスと一致します。 | grep 'go+gle' file.txt 「google」、「google」などには一致しますが、「ggle」には一致しません。 |
? |
前の文字または部分式の 0 個または 1 個のインスタンスと一致します。 | grep 'colou?r' file.txt 「色」と「色」が一致します。 |
[abc] |
文字セット内の任意の文字と一致します。 | grep '[aeiou]' file.txt 母音を含む行と一致します。 |
[0-9] |
任意の番号に一致します。 | grep '[0-9]' file.txt 数字を含む行と一致します。 |
[^abc] |
文字セットにない任意の文字と一致します。 | grep '[^0-9]' file.txt 数字を含まない行と一致します。 |
\d |
に相当する任意の数字と一致します[0-9] 。 |
grep '\d' file.txt 数字を含む行と一致します。 |
\D |
数値以外の文字と一致します。 と同等です[^0-9] 。 |
grep '\D' file.txt 数字を含まない行と一致します。 |
\w |
任意の 1 つの単語文字 (文字、数字、またはアンダースコア) と一致し、 と同等です[a-zA-Z0-9_] 。 |
grep '\w' file.txt 単語文字を含む行に一致します。 |
\W |
単語以外の文字と一致します。 と同等です[^a-zA-Z0-9_] 。 |
grep '\W' file.txt 単語文字を含まない行に一致します。 |
\s |
任意の空白文字 (スペース、タブ、改行など) と一致します。 | grep '\s' file.txt 空白文字を含む行と一致します。 |
\S |
空白以外の任意の文字と一致します。 | grep '\S' file.txt 空白文字を含まない行と一致します。 |
(pattern) |
一致するテキストをキャプチャするキャプチャ グループを作成します。 | grep 'a\(bc\)*d' file.txt 「ad」、「abcd」、「abcbcd」などに一致します。 |
` | ` | 論理 OR 演算子。2 つのパターンのいずれかに一致します。 |
.* |
0 個以上の任意の文字 (通常はテキスト行全体) に一致します。 | grep '.*pattern.*' file.txt 「パターン」を含む行と一致します。 |
6.3 文字のインターセプト、置換、および処理コマンド
6.3.1 カットコマンド
cut
命令用于从文本行中剪切或提取字段。默认情况下,cut
使用制表符(Tab)
作为字段分隔符,但可以通过-d
选项指定其他分隔符。它通常用于提取或删除文本文件中的特定列。
基本用法:
cut [OPTIONS] [FILE]
-
剪切文件中的第2列:
cut -f2 input.txt
-
使用逗号作为分隔符剪切第1和第3列:
cut -d',' -f1,3 input.csv
-
以特定字符作为字段分隔符,剪切第1列:
cut -d',' -f1 /etc/passwd
-
剪切每行的前5个字符:
cut -c1-5 input.txt
6.3.2 awk命令
awk
是一个强大的文本处理工具,它可以执行复杂的文本处理操作,包括文本提取、计算、条件筛选等。awk
将文本分割成字段,并允许对字段进行操作。它的灵活性使其成为处理结构化文本数据的理想工具。
基本用法:
awk 'pattern { action }' [FILE]
-
显示文件的第2列和第3列:
awk '{print $2, $3}' input.txt
-
计算文件中所有数字的总和:
awk '{ sum += $1 } END { print sum }' input.txt
-
使用逗号作为分隔符,打印第1列和第3列:
awk -F',' '{print $1, $3}' input.csv
-
打印包含特定模式的行:
awk '/pattern/ {print}' input.txt
6.3.3 sed命令
sed
(流编辑器)用于对文本进行基本的编辑和转换,如替换、删除、插入和替换。sed
可以通过正则表达式来匹配和操作文本,通常在管道中与其他命令一起使用。
基本用法:
sed [OPTIONS] 's/pattern/replacement/' [FILE]
-
替换文本文件中的所有"old"为"new":
sed 's/old/new/g' input.txt
-
删除包含特定字符串的行:
sed '/pattern/d' input.txt
-
在每行的开头插入文本:
sed 's/^/Prefix /' input.txt
-
将文件中的所有字母转换为大写:
sed 's/[a-z]/\U&/g' input.txt
6.4 sort、uniq、wc 命令
sort
、uniq
和wc
是在Linux和Unix系统上常用的命令,用于排序、去重和统计文本数据。
6.4.1 sort命令
sort
命令用于对文本文件的行进行排序。默认情况下,它按照字典顺序对文本行进行排序,但可以使用不同的选项来进行数字排序、逆序排序等。
基本用法:
sort [OPTIONS] [FILE]
-
对文件进行排序并将结果输出到标准输出:
sort input.txt
-
对文件进行数字排序(例如,按数值大小而不是字典顺序):
sort -n input.txt
-
对文件进行逆序排序:
sort -r input.txt
6.4.2 uniq命令
uniq
命令用于从已排序的文本数据中去重重复的行。它通常与sort
命令结合使用,以确保重复行相邻。
基本用法:
uniq [OPTIONS] [FILE]
-
从文件中去重重复的行:
sort input.txt | uniq
-
显示去重后的行以及它们重复的次数:
sort input.txt | uniq -c
6.4.3 wc命令
wc
命令用于统计文本文件的行数、字数和字符数。
基本用法:
wc [OPTIONS] [FILE]
-
统计文件的行数、单词数和字符数:
wc input.txt
-
仅统计行数:
wc -l input.txt
-
仅统计单词数:
wc -w input.txt
-
仅统计字符数:
wc -c input.txt
6.5 管道(Pipeline)
管道(Pipeline)是在Unix和类Unix操作系统中广泛使用的强大工具,它允许将一个命令的输出直接传递给另一个命令,以便进行复杂的数据处理和筛选。
管道(Pipeline)语法:
command1 | command2
command1
:第一个命令的输出将被传递给第二个命令。command2
:接收来自command1
的输入并进行处理的第二个命令。
6.6 grep命令
grep命令用于在文本中搜索匹配指定模式的行
grep命令语法:
grep [选项] 模式 [文件...]
选项
:可以是一些可选的标志,用于控制搜索的行为。模式
:要搜索的文本模式或正则表达式。文件
:要在其中搜索模式的一个或多个文件。如果省略文件参数,则grep将从标准输入中读取数据。
- 搜索文件中包含特定字符串的行:
grep "search_term" filename.txt
- 搜索多个文件中包含特定字符串的行:
grep "search_term" file1.txt file2.txt
- 搜索目录中所有文件包含特定字符串的行:
grep "search_term" /path/to/directory/*
- 搜索多个文件并显示匹配行的行号:
grep -n "search_term" file1.txt file2.txt
- 忽略大小写进行搜索:
grep -i "search_term" filename.txt
- 使用正则表达式进行高级搜索(例如,查找以"abc"开头的行):
grep "^abc" filename.txt
- 逆向搜索,即只显示不匹配模式的行:
grep -v "search_term" filename.txt
- 递归搜索目录中的文件:
grep -r "search_term" /path/to/directory/
- 搜索匹配模式的行并统计匹配的次数:
grep -c "search_term" filename.txt
7. 输入输出重定向
7.1 Linux标准输入
类型 | 设备 | 设备名 | 文件描述符 | 类型 |
---|---|---|---|---|
标准输入(stdin) | 键盘 | /dev/stdin | 0 | 标准输入 |
标准输出(stdout) | 显示器 | /dev/stdout | 1 | 标准输出 |
标准错误输出(stderr) | 显示器 | /dev/stderr | 2 | 标准错误输出 |
7.2 输入重定向
类型 | 符号(语法) | 功能 |
---|---|---|
标准输入 | 命令 < 文件1 | 命令将文件1的内容作为标准输入设备 |
标识符限定输入 | 命令 << 标识符 | 命令将标准输入中读入内容,直到遇到“标识符”分隔符为止 |
输入输出重定向 | 命令 < 文件1 > 文件2 | 命令将文件1的内容作为标准输入,将文件2作为标准输出。 |
7.3 输出重定向
类型 | 符号 | 作用 |
---|---|---|
標準出力のリダイレクト (オーバーライド) | コマンド > ファイル | 上書きモードでは、コマンドの正しい出力内容を指定したファイルまたはデバイスに出力します。 |
標準出力のリダイレクト (追加) | コマンド>>ファイル | 追加モードでは、コマンドの正しい出力内容を指定されたファイルまたはデバイスに出力します。 |
標準エラー出力のリダイレクト (オーバーライド) | エラー コマンド 2> ファイル | コマンドのエラー出力を指定したファイルまたはデバイスに上書きモードで出力します。 |
標準エラー出力のリダイレクト (追加) | エラー コマンド 2>> ファイル | 追加モードでは、コマンドのエラー出力を指定されたファイルまたはデバイスに出力します。 |
stdout と stderr の両方を保存 (上書き) | コマンド>ファイル2>&1 | オーバーレイ モードでは、正しい出力とエラーの出力の両方を同じファイルに保存します |
標準出力と標準エラー出力の両方を保存(追加) | コマンド>>ファイル2>&1 | 追加モードでは、正しい出力とエラー出力の両方を同じファイルに保存します |
stdout と stderr の両方を保存 (上書き) | コマンド&>ファイル | オーバーレイ モードでは、正しい出力とエラーの出力の両方を同じファイルに保存します |
標準出力と標準エラー出力の両方を保存(追加) | コマンド&>>ファイル | 追加モードでは、正しい出力とエラー出力の両方を同じファイルに保存します |
正しい出力とエラー出力を別々に保存する | コマンド > ファイル 1 2 > ファイル 2 | 正しい出力をファイル 1 に保存し、エラー出力をファイル 2 に保存します。 |
7.4 /dev/null
出力を画面に表示せずにコマンドを実行したい場合は、/dev/null
出力をファイルにリダイレクトすることで出力を完全に破棄できます。
例:
command > /dev/null
このコマンドは、コマンドの標準出力を/dev/null
ファイルにリダイレクトし、出力を完全に破棄します。