このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

Linuxコマンドの基本:シェルスクリプト:コマンドライン引数とfor文

シェルスクリプト:コマンドライン引数とfor文

 シェルスクリプトでは、for 文とコマンドライン引数を組み合わせて、指定されたすべての引数に対して繰り返し処理を行うことができます。特に、$@ をリストとして指定することで、すべてのコマンドライン引数を順に処理することが可能です。ここでは、その方法について詳しく解説します。

コマンドライン引数を利用したfor文の基本

 for 文では、リストとして "$@" を指定することで、すべてのコマンドライン引数を順に取り出して処理することができます。

例:コマンドライン引数を表示するスクリプト(for-args.sh

スクリプトの作成

user01@ubuntu:~$ nano for-args.sh

for-args.sh の内容

#!/bin/bash

for arg in "$@"
do
  echo "$arg"
done

解説

  • for arg in "$@";:すべてのコマンドライン引数を arg という変数に順に代入します。
  • echo "$arg"arg の値を表示します。

実行権限の付与

user01@ubuntu:~$ chmod +x for-args.sh

スクリプトの実行

user01@ubuntu:~$ ./for-args.sh "Hello World" system.log 123 directory
Hello World
system.log
123
directory

解説

  • コマンドライン引数として "Hello World"system.log123directory を指定しています。
  • スクリプトはこれらの引数を順に表示します。

in 以下の省略について

 for 文では、リストを指定しない場合、自動的に $@ がリストとして使用されます。つまり、以下の2つの書き方は同じ意味になります。

for arg in "$@"
do
  # 処理
done
for arg
do
  # 処理
done

しかし、コードの可読性を高めるために、in "$@" を明示的に書くことを推奨します。

スクリプトの作成:ファイルサイズと行数を表示するスクリプト(file-info.sh

 このスクリプトでは、コマンドライン引数で指定されたファイルやディレクトリに対して以下の処理を行います。

  • ディレクトリの場合:ディレクトリ内のファイル数を表示します。
  • 通常ファイルの場合:ファイルのサイズと行数を表示します。

スクリプトの作成

user01@ubuntu:~$ nano file-info.sh

file-info.sh の内容

#!/bin/bash

for item in "$@"
do
  if [ -d "$item" ]; then
    echo "'$item' はディレクトリです。"
    count=$(ls -1 "$item" | wc -l)
    echo "ファイル数: $count"
  elif [ -f "$item" ]; then
    echo "'$item' は通常のファイルです。"
    size=$(stat -c%s "$item")
    lines=$(wc -l < "$item")
    echo "サイズ: $size バイト, 行数: $lines"
  else
    echo "'$item' は存在しないか、特殊なファイルです。"
  fi
done

解説

  • for item in "$@";:すべてのコマンドライン引数を item 変数に順に代入します。
  • if [ -d "$item" ]; thenitem がディレクトリかどうかを判定します。
  • ディレクトリの場合:
    ls -1 "$item" | wc -l:ディレクトリ内のファイル数をカウントします。
  • elif [ -f "$item" ]; thenitem が通常のファイルかどうかを判定します。
  • 通常ファイルの場合
    tat -c%s "$item":ファイルのサイズを取得します。
    wc -l < "$item":ファイルの行数を取得します。
  • その他の場合
    '存在しないか、特殊なファイルです。' と表示します。

実行権限の付与

user01@ubuntu:~$ chmod +x file-info.sh

スクリプトの実行

テスト用のファイルとディレクトリの作成

user01@ubuntu:~$ mkdir test_dir
user01@ubuntu:~$ touch test_dir/file1.txt test_dir/file2.txt
user01@ubuntu:~$ echo -e "Line 1\nLine 2\nLine 3" > test_file.txt

スクリプトの実行例

user01@ubuntu:~$ ./file-info.sh test_dir test_file.txt nonexistent.txt

出力結果

user01@ubuntu:~$ ./file-info.sh test_dir test_file.txt nonexistent.txt
'test_dir' はディレクトリです。
ファイル数: 2
'test_file.txt' は通常のファイルです。
サイズ: 21 バイト, 行数: 3
'nonexistent.txt' は存在しないか、特殊なファイルです。

解説

  • test_dir
    ・ディレクトリであり、ファイル数が2つであることが表示されます。
  • test_file.txt
    ・通常ファイルであり、サイズが21バイト、行数が3行であることが表示されます。
  • nonexistent.txt
    ・存在しないファイルであるため、その旨が表示されます。

作成したファイルとディレクトリの削除

user01@ubuntu:~$ rm -r test_dir
user01@ubuntu:~$ rm test_file.txt
user01@ubuntu:~$ rm file-info.sh
user01@ubuntu:~$ rm for-args.sh 

まとめ

  • for 文とコマンドライン引数$@ をリストとして指定することで、すべてのコマンドライン引数に対して繰り返し処理を行うことができます。
  • リストの省略for 文で in 以下を省略すると、デフォルトで $@ が使用されますが、可読性のために明示的に書くことをおすすめします。
  • 実用的なスクリプトの作成file-info.sh のように、コマンドライン引数と for 文を組み合わせることで、ファイルやディレクトリに対するさまざまな処理を自動化できます。
  • エラーハンドリング:指定されたパスが存在しない場合や特殊なファイルの場合にも対応することで、スクリプトの信頼性を高めることができます。

これらの知識を活用して、シェルスクリプトでより高度な自動化や効率化を実現してみてください。