Lubuntu 学習教材自動作成スクリプト

作りは泥臭いのですが、一応必要としているスクリプトは完成したので、次の課題。

学習教材自動作成スクリプトといっても、Linuxの学習教材ではありません。
簡単な、計算問題の作成が職業上必要だからです。

仕様を、作成する前に乱数が必要なのがわかっているので、調べた内容を最初に記しておきます。

<乱数の取得>

user@Dimension-2400C:~$ ( for val in `od -vAn -tu1 -N8 </dev/urandom` ; do echo $((val % 100)) ; done )
52
13
50
60
30
38
0
99

上記のコマンドで2桁の乱数が8つ取得出来ます。

とここまで、書いたのですが、職場のExcelでものの30分もしないうちに目的のものが出来てしまいました。それも、教育に必要なほとんどのパターンを網羅し、無限に新しい問題集を一瞬で作成できます。
とりあえず、これはお蔵入りということで、また新たな必要性が生まれたら書きます。

lubuntu 初めてのシェルスクリプト その2

URLリストをもとに、youtubeから音源抽出するスクリプトの作成。単独URL指定、複数URL指定(無制限)、URLリスト指定のいづれにも対応とする。
コマンド名:youtube-dlm

(仕様)
#!/bin/bash
###################################################
#youtube-dlm (Extraction music from youtube movie)#
###################################################
#(usage)
#youtube-dlm url1 url2 url3 …. urln
#youtube-dlm -l (use music_url_list)
#youtube-dlm -l url_list
###################################################
#syorikubun変数宣言
#youtube-dlがインストールされているかチェック
##ない場合、「youtube-dlをインストールしてください」のメッセージ
##スクリプトを終了
#URLチェック関数 chkurlを定義 戻り値にOKの時0,NGの時1をセット
#音源抽出関数 cyuusyutuを定義 抽出に失敗すれば「urlの抽出に失敗しました」のメッセージを出力。結果はcyuusyutuokにOKの時”ok”NGの時”ng”をセット
#youtube-dl -x $1 で抽出
#全URLチェック関数 allchkurlを定義 すべての引数についてURLチェックを行い、エラーのURLがあれば「XXXXは不正なURLです」のメッセージを出力し、スクリプトを終了。
#URLチェックがすべてOKならば、処理区分に、bをセット。
#URLをチェック
#引数のパターンにより処理区分をセット
#処理区分
#a:単独URLによる音源抽出
#b:複数URLによる音源抽出
#c:オプション-lでURLリスト指定による音源抽出
#d:オプション-lでリスト指定無し、music_url_listによる音源抽出
#引数の個数をチェック
##引数が0の時
###メッセージを表示、スクリプトを終了
##引数が1つの時
###-lの時
####music_url_listの存在チェックを行い、存在すれば処理区分にdをセットする
###それ以外の時、関数chkurlを実行
###urlokがokの時処理区分にaをセット
###urlokがngの時、「URLを指定してください」のメッセージ表示、スクリプトを終了
##引数が2の時
###$1が-lの時、$2のファイル存在チェック、OKであれば、処理区分にcをセット
###$1がそれ以外の場合、allchkurlを実行。
###$1が3以上の場合、allchkurlを実行。
#以下処理区分により分岐
###処理区分がaの時 $1を引数にcyuusyutu実行。
###処理区分がbの時 $@を引数にcyuusyutu実行。
#音楽抽出
###処理区分がcの時 URLリストを全件読込、cyuusyutuを実行。
###処理区分がdの時 music_url_listを全件読込、URLチェックOKの場合、cyuusyutuを実行。
###処理区分が””の時 「想定外のエラーが発生しました」のメッセージ表示。

以上の仕様を実装するために必要な知識を調べます。

<すべての引数についてループ>

for arg in “$@”
do
処理 #引数の参照は、”$arg”で
done
<シェル関数>

スクリプト内で一定の処理を関数として定義して、使用することが出来ます。

定義

関数名()
{
処理
}

実行

関数名 [引数]

シェル関数の実行には引数をつけることができ、シェル関数内の位置パラメータは、一時的にシェル関数の引数で一時的に置き換えられます。
シェル関数の終了ステータスは、シェル関数内で最後に実行されたリストの終了ステータスになります。
シェル関数内の変数はグローバル変数のように扱われます。たとえば、シェル関数内で変数に値を代入すると、シェル関数からリターンした後も、その変数には値が代入されたままになります。
シェル関数の定義では{の記号が正しく認識されるように、{の直後には区切り文字としてのスペースまたは改行が必要です。
<シェルスクリプトの終了>

exitコマンドを実行すると、その時点でシェルスクリプトが終了します。引数で終了ステータスを指定できます。

構文 exit [終了ステータス]
<ファイルの存在チェック>

ファイルの存在チェックにはtestコマンドを用います。

test -f ファイルパス

真ならば終了ステータスは0、偽ならば終了ステータスは1になります。

<ファイルを1行ずつ読んでループする>

ファイルから、1行ずつ読込みループするには、「while read」の形式を使います。

while read line
do
echo $line
done < ファイルパス

<cace文>

case 文は C言語や Java言語の switch 文に該当する制御文で、if 文と同じように処理を分岐するために使用されるものです。分岐条件には判定対象となる 1つの値と、その値と照合される複数のパターンを指定します。

構文

case 値 in
パターン1 ) 処理1 ;;
パターン2 ) 処理2 ;;
パターン3 ) 処理3 ;;

パターンn ) 処理n ;;
esac

< アプリケーションの存在確認 >

typeコマンドを使用します。通常typeコマンドは、コマンドに関する情報を表示するコマンドです。ここでは、if文の条件式の中で使われていますが、コマンドの結果が0であれば、真と同じ意味になります。

if type アプリケーション > /dev/null 2>&1 ; then
echo “存在します”
else
echo “存在しません”
fi

<Geditの行数表示>

スクリプトが長くなってきたので、行数を表示するように設定します。
私は、もっぱらGeditを使用しているので、編集→設定→表示タブ→行番号を表示するにチェックでOKです。

以下以上の内容を使って作成したシェルスクリプトです。

#!/bin/bash
###################################################
#youtube-dlm (Extraction music from youtube movie)#
###################################################
#(usage)
#youtube-dlm url1 url2 url3 …. urln
#youtube-dlm -l (use music_url_list)
#youtube-dlm -l url_list
###################################################
#syorikubun変数宣言
syorikubun=””
#youtube-dlがインストールされているかチェック
if type youtube-dl > /dev/null 2>&1 ; then
:
else
##ない場合、「youtube-dlをインストールしてください」のメッセージ
echo “youtube-dlをインストールしてください”
##スクリプトを終了
exit
fi
#URLチェック関数 chkurlを定義 戻り値にOKの時0,NGの時1をセット
chkurl() {
urlcheck=$( wget –spider -nv -t 1 $1 2>&1 | grep -c ‘200 OK’ )
if test $urlcheck -eq 1; then
urlok=0
else
urlok=1
fi
return $urlok
}
#音源抽出関数 cyuusyutuを定義 抽出に失敗すれば「urlの抽出に失敗しました」のメッセージを出力。結果はcyuusyutuokにOKの時”ok”NGの時”ng”をセット
cyuusyutu() {
#youtube-dl -x $1 で抽出
youtube-dl -x $1 | grep Destination
return $?
}
#全URLチェック関数 allchkurlを定義 すべての引数についてURLチェックを行い、エラーのURLがあれば「XXXXは不正なURLです」のメッセージを出力し、スクリプトを終了。
#URLチェックがすべてOKならば、処理区分に、bをセット。
allchkurl() {
for x in “$@”
do
#URLをチェック
if chkurl “$x”;then
syorikubun=”b”
else
echo “$x”は不正なURLです。;exit
fi
done
if test $syorikubun==”b”;then
rtn=0
else
rtn=1
fi
return $rtn
}
#引数のパターンにより処理区分をセット
#処理区分
#a:単独URLによる音源抽出
#b:複数URLによる音源抽出
#c:オプション-lでURLリスト指定による音源抽出
#d:オプション-lでリスト指定無し、music_url_listによる音源抽出
#引数の個数をチェック
##引数が0の時
if test $# -eq 0;then
###メッセージを表示、スクリプトを終了
echo “URLまたは、オプション-l を指定してください。”;exit
fi
##引数が1つの時
if test $# -eq 1;then
if test $1 == “-l”;then
###-lの時
####music_url_listの存在チェックを行い、存在すれば処理区分にdをセットする
if test -f ./music_url_list;then
syorikubun=”d”
else
echo “music_url_listが存在していません”;exit
fi
###それ以外の時、関数chkurlを実行
else
###urlokがokの時処理区分にaをセット
if `chkurl $1`;then
syorikubun=”a”
else
###urlokがngの時、「URLを指定してください」のメッセージ表示、スクリプトを終了
echo “正しいURLを指定してください”;exit
fi
fi
fi
##引数が2の時
if test $# -eq 2;then
###$1が-lの時、$2のファイル存在チェック、OKであれば、処理区分にcをセット
if test $1 == “-l”;then
if test -f $2;then
syorikubun=”c”
else
echo $2″がURLリストとして存在していません”;exit
fi
###$1がそれ以外の場合、allchkurlを実行。
else
allchkurl “$@”
fi
fi
if test $# -ge 3;then
###$1が3以上の場合、allchkurlを実行。
allchkurl “$@”
fi
#以下処理区分により分岐
case $syorikubun in
###処理区分がaの時 $1を引数にcyuusyutu実行。
“a” ) cyuusyutu $1;;
###処理区分がbの時 $@を引数にcyuusyutu実行。
“b” ) bcnt=0
for x in “$@”
do
#音楽抽出
cyuusyutu “$x”
bcnt=`expr $bcnt + 1`
done
echo $bcnt “件を処理しました”
;;
###処理区分がcの時 URLリストを全件読込、cyuusyutuを実行。
“c” ) ecnt=0
while read line
do
if `chkurl $line`;then
:
else
ecnt=`expr $ecnt + 1`
echo $line “は不正なURLです”
exit
fi
done < “$2”
cnt=0
while read line
do
cnt=`expr $cnt + 1`
cyuusyutu $line
done < “$2”
echo $cnt “件を処理しました”
;;
###処理区分がdの時 music_url_listを全件読込、URLチェックOKの場合、cyuusyutuを実行。
“d” ) ecnt=0
while read line
do
if `chkurl $line`;then
:
else
ecnt=`expr $ecnt + 1`
echo $line “は不正なURLです”
exit
fi
done < ./music_url_list
cnt=0
while read line
do
cnt=`expr $cnt + 1`
cyuusyutu $line
done < ./music_url_list
echo $cnt “件を処理しました”
;;
###処理区分が””の時 「想定外のエラーが発生しました」のメッセージ表示。
“” ) echo “想定外のエラーが発生しました” ;;
esac

結構、スクリプトが長いのでテストパターンを作成しテストしました。

youtube-dlがインストールされている場合●
youtube-dlがインストールされていない場合●
パラメータなしで起動●
1つの正しいurlをパラメータで起動●
2つの正しいurlをパラメータで起動●
3つの正しいurlをパラメータで起動●
1つの誤ったurlをパラメータで起動●
1つの正しいurlと1つの誤ったurlで起動●
2つの正しいurlと1つの誤ったurlで起動●
4つの正しいurlで起動●
オプション-l のみのパラメータでmusic_url_listが存在し、複数のurlが登録されている場合●
オプション-l のみのパラメータでmusic_url_listが存在し、複数のurlが登録されていて、誤ったurlを含む場合●
オプション-l のみのパラメータでmusic_url_listが存在し、urlが登録されていない場合●
オプション-l で指定のurlリストファイルが存在し、複数のurlが登録されている場合●
オプション-l で指定のurlリストファイルが存在し、複数のurlが登録されていて、誤ったurlを含む場合●
オプション-l で指定のurlリストファイルが存在し、urlが登録されていない場合●

思ったよりも、文法エラー・構文エラーなどで苦労しました。あと、全角スペースを入れないように気をつけなければならないことを学びました。

Lubuntu 初めてのシェルスクリプト

前回の記事に基づき、youtube閲覧中に気になる音源があればすぐにURLリストに登録できるスクリプトの作成を行います。

その前に、一番簡単なシェルスクリプトを作成して、動作確認を行います。

#!/bin/sh

echo “Hello,World!!”

以上の簡単なスクリプトをhelloworld.shとしてカレントディレクトリに作成

$ chmod u+x helloworld.sh

として実行権限を与えます

$ helloworld.shと打っても動作しません

$ helloworld.sh
helloworld.sh: コマンドが見つかりません

 

原因は、パスが通っていない=環境変数 $PATHにホームディレクトリが含まれていないからでした。そこで、

$ ./helloworld.sh
Hello,World!!

上記のように明示的にパスを指定してあげると動作しました。

 

それでは、まず処理の簡単な仕様を作成します。

#コマンド名 addmurl
#(引数の個数は1とする。)
#引数が1個の場合
#URLのアクセスチェック
#チェックOKの場合
#URLの重複チェックを行う
#URLに重複がない場合
#URLをmusic_dl_listに追記する。
#URLに重複がある場合
#メッセージ***このURLはすでに登録されています。***を表示して終了
#チェックNGの場合
#メッセージ**引数に有効なURLを指定してください**を表示して終了
#引数が1個以外の場合
#メッセージ**URLを1つだけ指定してください。**を表示して終了

 

仕様は以上のような簡単なものです。

上記のシェルスクリプト作成にあたって必要なのは、条件分岐です。ifを用います。他に、URLのアクセスチェックを行うためにwgetを使用します。また、if文の条件にtestコマンドを用います。加えて、特殊変数を用いてパラメータの情報を使用します。

if文

条件分岐で一番ポピュラーなのが、他言語でも多く用いられるif文です。

基本になるのが以下のような構文です。

if 条件式1 ; then
処理1
else
処理2
fi

条件判断が複数になる場合以下のような構文が用いられます

if 条件式1 ; then
処理1
elif 条件式2 ; then
処理2
else
処理3
fi

if文の条件式の部分は実際は、testコマンドで記されます。

testコマンド

構文は

数値の比較の場合

test 数値1(式) 比較演算子 数値2(式)

というような形式で使われます。

比較演算子は次のようなものが使われます。

-eq → equal(= と同等)
-ne → not equal(!= と同等)
-lt → less than (< と同等)
-le → less than or equal(<= と同等)
-gt → greater than(> と同等)
-ge → greater than or equal(>= と同等)

文字列の比較の場合

test 文字列 比較演算子 文字列

比較演算子は次のようなものが使われます。

文字列1 = 文字列2 (文字列1と文字列2が同じならば真)
文字列1 == 文字列2 (文字列1と文字列2が同じならば真(上と同じ))
文字列1 != 文字列2 (文字列1と文字列2が異なれば真)

使用例 test hoge -lt 1 (hogeが1より小さい時)

testが単独で使用される場合結果は、条件が成り立つ場合に真(0)成り立たない場合は偽(1)を返します。真(0) か偽(1) かの終了ステータスを返すのみで、画面上へのメッセージ出力等は一切行われません。終了ステータスは、特殊変数 $? で確認できます。

testコマンドには、これ以外にもたくさん機能があるので別途研究します。

wgetコマンド(ファイルをFTPサーバーやWebサーバーからダウンロードする。)

通常、ファイルのダウンロードに用いますが、今回は、アクセスチェックに用います。

オプションとして以下のものを用います。

–spider ファイルをダウンロードしない。

-nv 冗長メッセージを出力せず、エラーメッセージと基本情報のみを出力。

-t 接続拒否や 404 が返ってきたときに再試行する回数。デフォルトは 20回。

特殊変数

シェルスクリプトに引数を与えたい時があります。そんな時に、引数を参照できる特殊変数というものがあります。

特殊変数は以下のものが使用可能です

特殊変数 意味
$0 シェルスクリプトの名前
$n n番目の引数
$* すべての引数リスト
$# 与えられた引数の数
$? 直前に実行したコマンドの戻り値
$$ シェルスクリプトが実行された際のPID
$LINENO この変数を記述した行番号

上記以外にも特殊変数には使い方があるので別途研究します。

以下以上の内容を使って作成したシェルスクリプトです。

#!/bin/bash
######################################
#addmurl (add url to music_url_list) #コマンド名 addmurl
######################################
if test $# -eq 1;then #引数が1個の場合
# URLのアクセスチェック
urlcheck=$( wget –spider -nv -t 1 $1 2>&1 | grep -c ‘200 OK’ )
if test $urlcheck -eq 1;then
# urlチェックの値が1の時、URLの重複チェックを行う
dupcnt=$( cat music_url_list | grep -c $1 )
if test $dupcnt -eq 0;then
# URLに重複がない場合
# music_url_listにurlを追記する。
echo $1 >>music_url_list
else
# URLに重複がある場合
#メッセージ***このURLはすでに登録されています。***を表示して終了
echo “このURLはすでに登録されています。”
fi
else
echo “正しいurlを指定してください。”   #チェックNGの場合
fi
else
echo “URLを1つだけ指定してください。”  #引数が1個以外の場合
fi

上記のように作成実行しましたが、

$ ./addmurl https://www.youtube.com/watch?v=3fF_XqQDkI
./addmurl: 行 26: 構文エラー: 予期しないファイル終了 (EOF) です

とエラーメッセージが表示されました。
ググっているとどうも改行コードに不正なものが含まれているようです。
原因として考えられるのは、コード作成に自宅のubuntuと職場のCygwinを併用していたことにありそうです。

どうやって確認するかをググっているとodコマンドを使うと、確認できるのを発見しました。

$ od -c ./addmurl

で実行

0000000 # ! / b i n / b a s h \n # # # #
0000020 # # # # # # # # # # # # # # # #
*
0000060 # # \n # a d d m u r l ( a d d
0000100 u r l t o m u s i c _ u r
0000120 l _ l i s t ) # 343 202 263 343 203 236
0000140 343 203 263 343 203 211 345 220 215 a d d m u r
0000160 l \n # # # # # # # # # # # # # #
0000200 # # # # # # # # # # # # # # # #
0000220 # # # # # # # # \n i f t e s t
0000240 $ # – e q 1 ; t h e n
0000260 # 345 274 225 346 225 260 343 201 214 1 345 200 213
0000300 343 201 256 345 240 264 345 220 210 \n # 343 200 200 U R
0000320 L 343 201 256 343 202 242 343 202 257 343 202 273 343 202 271
0000340 343 203 201 343 202 247 343 203 203 343 202 257 \n 343 200 200
0000360 343 200 200 u r l c h e c k = $ ( w
0000400 g e t – – s p i d e r – n v
0000420 – t 1 $ 1 2 > & 1 |
0000440 g r e p – c ‘ 2 0 0 O K ‘
0000460 ) \n i f t e s t $ u r
0000500 l c h e c k – e q 1 ; t h e
0000520 n \n # 343 200 200 u r l 343 203 201 343 202 247 343
0000540 203 203 343 202 257 343 201 256 345 200 244 343 201 214 357 274
0000560 221 343 201 256 346 231 202 343 200 201 U R L 343 201 256
0000600 351 207 215 350 244 207 343 203 201 343 202 247 343 203 203 343
0000620 202 257 343 202 222 350 241 214 343 201 206 \n
0000640 d u p c n t = $ ( c a t m u
0000660 s i c _ u r l _ l i s t | g
0000700 r e p – c $ 1 ) \n
0000720 i f t e s t $ d u p c n t
0000740 – e q 0 ; t h e n \n # 343 200 200 U
0000760 R L 343 201 253 351 207 215 350 244 207 343 201 214 343 201
0001000 252 343 201 204 345 240 264 345 220 210 \n # 343 200 200 m
0001020 u s i c _ u r l _ l i s t 343 201 253
0001040 u r l 343 202 222 350 277 275 350 250 230 343 201 231 343
0001060 202 213 343 200 202 \n 343 200 200 343 200 200 e
0001100 c h o $ 1 > > m u s i c
0001120 _ u r l _ l i s t \n e l
0001140 s e \n # 343 200 200 U R L 343 201 253 351 207 215
0001160 350 244 207 343 201 214 343 201 202 343 202 213 345 240 264 345
0001200 220 210 \n # 343 203 241 343 203 203 343
0001220 202 273 343 203 274 343 202 270 * * * 343 201 223 343 201
0001240 256 U R L 343 201 257 343 201 231 343 201 247 343 201 253
0001260 347 231 273 351 214 262 343 201 225 343 202 214 343 201 246 343
0001300 201 204 343 201 276 343 201 231 343 200 202 * * * 343 202
0001320 222 350 241 250 347 244 272 343 201 227 343 201 246 347 265 202
0001340 344 272 206 \n e c h o ” 343
0001360 201 223 343 201 256 U R L 343 201 257 343 201 231 343 201
0001400 247 343 201 253 347 231 273 351 214 262 343 201 225 343 202 21
以下略

のような感じで表示されます。
不正な改行コードが入っている場合\r\nと記載されるということです。
見たところ、\r\nの記載はありません。
そこで、原始的な方法ですが、エラーメッセージの出ている行のコマンドの前後のスペースを打ち直すということを行い、正常に動作するようになりました。今後、WindowsのCygwin環境でコードを作成するのはやめにしようと思います。以下完成版のシェルスクリプトです。

#!/bin/bash
######################################
#addmurl (add url to music_url_list) #コマンド名 addmurl
######################################
if test $# -eq 1;then #引数が1個の場合
# URLのアクセスチェック
urlcheck=$(wget –spider -nv -t 1 $1 2>&1 | grep -c ‘200 OK’)
if test $urlcheck -eq 1;then
# urlチェックの値が1の時、URLの重複チェックを行う
dupcnt=$( cat ./music_url_list | grep -c $1 )
if test $dupcnt -eq 0;then
# URLに重複がない場合
# music_url_listにurlを追記する。
echo $1 >>music_url_list
echo $1 “を登録しました”
else
# URLに重複がある場合
#メッセージ***このURLはすでに登録されています。***を表示して終了
echo “このURLはすでに登録されています。”
fi
else
#URLチェックNGの場合
echo “正しいURLを指定してください。”
fi
else
#引数が1個以外の場合
echo “URLを1つだけ指定してください。”
fi

以上のシェルスクリプトを実行する時に、コマンド名の前に、いちいち./を付けなくてはなりません。そこで、パスの通ったディレクトリにシェルスクリプトをコピーすることにします。

パスの通っているディレクトリは、環境変数PATHを確認すれば、OKです。

$ echo $PATH
/home/user/bin:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

ここで/home/user/bin /home/user/.local/bin などにパスが通っているのがわかります。今回は、/home/user/binにコマンドをコピーします。

$ mkdir /home/user/bin
$ cp ./addmurl /home/user/bin/addmurl

実行してみます

$ addmurl dummyurl
正しいURLを指定してください。

うまく行きました。

もうひとつ考慮しておくべきことがあります。それは、スクリプト中のファイルパスを相対参照にしておく必要があるということです。やることは簡単で、music_url_listを./music_url_listに変更してあげるだけです。

Lubuntuシェルスクリプト学習予定

現在、とある書籍に従いLinuxの学習を進めていたのですが、当初は、物珍しさも手伝って短いスパンで投稿できるほど、学習も進んでいたのですがここに来て、早くも倦怠期のようです。
直近の目標である、シェルスクリプト作成については、テキストでは後半の方にあり中々たどり着きません。そこで、少し方針を変えて、具体的なシェルスクリプト作成の課題を自分に課して、モチベーチョンを上げようというところです。
具体的な課題がないと学習も中々進まないものです。

ところで、私のLinux利用は、Windowsの代替というところから始まっています。
もともとの使いみちも、メール、会計(バンド活動の)、音楽プレーヤー、楽譜のやり取り、ショッピングといたってシンプルなものです。今回は、youtubeからの音源取得の省力化を目標にします。

具体的には、
1.youtube閲覧中に気になる音源があればすぐにURLリストに登録できるスクリプトの作成。

2.リストをもとに、音源抽出するスクリプトの作成。引数として単独URL指定、複数URL指定、URLリスト指定のいづれにも対応とします。ファイル名の自動最適化機能を備えます。

3.Musicフォルダへの自動コピースクリプト作成。同名ファイルの自動判定と音質による置き換えガイダンス機能を装備します。(自動化が困難なため中止)

以上を目標に学習を進める予定です。

Lubuntu エスケープ・コマンド置換・コマンドの連続実行

特殊文字のエスケープ

いくつかの記号について,特殊な意味を持っているものがあります。

” $ @ & ‘ ( ) ^ | [ ] { } ; * ? < > ` \ スペース
改行,タブといったエスケープ・シーケンス

がそうです。

これらを使用する時には、シングルクォーテーションやダブルクォーテーションで囲ったり、特殊文字の前にバックスラッシュを付けたりします。

他に目に見えない文字、(改行など)にはエスケープシーケンスを利用します。

以下のようなものがあります。

\b バック・スペース
\n 改行

コマンドの置換

コマンドラインの一部または全部を、コマンドラインの出力で置き換え出来ます。

方法1 $(コマンド)

(例)
user@Dimension-2400C:~$ echo Data: $(date)
Data: 2017年 5月 27日 土曜日 20:28:58 JST
方法2  `コマンド` #バッククォーテーションで囲む
(例)
user@Dimension-2400C:~$ echo Data: `date`
Data: 2017年 5月 27日 土曜日 20:29:16 JST

コマンドの連続実行

以下のように、;(セミコロン)、&&、||を使いコマンドを連続実行することが出来ます。

コマンド1 ; コマンド2 ・・・・・・コマンド1の結果にかかわらずコマンド2が実行されます。

コマンド1 && コマンド2 ・・・・・コマンド1が成功した場合のみコマンド2が実行されます。

コマンド1 || コマンド2 ・・・・・コマンド1が失敗した場合のみコマンド2が実行されます。

&&や||を使って、条件分岐にも使用できるのがわかります。

(例)
user@Dimension-2400C:~$ cd test
user@Dimension-2400C:~/test$ ls
magofile1 magofile2 siftjis.txt test
user@Dimension-2400C:~/test$ touch arufairu
user@Dimension-2400C:~/test$ test -f arufairu && echo “arufairuはあります。”
arufairuはあります。
user@Dimension-2400C:~/test$ test -f naifairu || echo “naifairuはありません。”
naifairuはありません。
user@Dimension-2400C:~/test$

上の例では、testコマンドを使っています。testコマンドは、非常に有用なコマンドなので別途解説しますが、今回は、オプション -fを使ってファイルの存在チェックを行っています。
test -f ファイルパスでファイルが存在すれば、0(true)(成功)、存在しなければ1(false)(失敗)を返します。

Lubuntu シェル変数と環境変数

シェル変数

シェルでは、他のプログラム言語と同様に、変数を定義して使用することが出来ます。
つまり、プログラム言語としての側面を持ちあわせていると言えます。
シェル変数とは、シェル内で定義して、そのシェル内でしか参照出来ない変数です。
変数の命名には、アルファベット、数字、アンダーバーを使えますが、先頭を数字にすることは出来ません。また、大文字と小文字は区別されます。

シェル変数の定義

シェル変数の定義は

変数名=値

という形で行われます。イコールの前後にスペースがあってはいけません。また、代入する値にスペースがある場合は、ダブルクォーテーションでくくる必要があります。
シェル変数には、型がなくすべての値を文字列として扱います。

シェル変数の参照

シェル変数の参照には

$変数名 という形で、変数名の頭に$を付けます。

また、変数を中括弧{ }でくくって記述できます。

${変数名}

値を設定していない変数は空の値が設定されているものと解釈されます。

(例)
user@Dimension-2400C:~$ kakutyousi=opus
user@Dimension-2400C:~$ echo $kakutyousi
opus

また、シェル変数はファイルパスの一部としても使用出来ます。

ファイル名の色の謎.png

##余談#################################
ここで気になることが1つあります、2つだけ他のファイルと色が違います。
ls -l で詳細を確認してみます。
Delirioフォルダー詳細.png今まで、意図的にパーミッションを変えたことが無いのに、ほとんどのファイルのotherのアクセス権がゼロに変わっています。思い当たるふしは、音楽ファイルをファイルマネージャでスマホにコピーしようとドラッグした際に移動になってしまったので、コピーし戻したことがあります。
実際に、再現してみます。
すると、今回はちゃんと移動ではなくコピーされました。コピー先のパーミッションは、所有者のみアクセス可になっています。この辺の挙動がよく分かっていないので今後、勉強していきます。
################余談終わり################

環境変数

前述のように、シェル変数は、シェル内で定義してそのシェル内でしか使えない変数です。それに対して、シェルから他のプログラムを起動した時にも使える変数を環境変数と言います。環境変数の値は、各プログラムから参照することが出来ます。

シェル変数と環境変数

多くの環境変数がシェルの設定ファイルで予め設定されています。
環境変数だけを確認するためには、printenvコマンドを使用します。

printenv実行.png

ユーザーが環境変数を作成するには、exportコマンドを使います。最初から環境変数として作成する方法と、シェル変数として作成してあとから格上げする方法があります。

export 変数名=値

または

変数名=値
export 変数名

デフォルトで設定されている環境変数は、安易な変更・削除は行わないようにしましょう。

それでは、よく使われる環境変数について少し見てみます。

PATH

コマンドサーチパスを設定しています。プロンプトから例えばgeditコマンドを入力してgeditが起動されるのは、PATH環境変数に/usr/binが設定されていて、/usr/bin/geditを見に行くからです。下に現在、私の環境で設定されているPATH環境変数の中身を表示しましたが、これはprintenvを実行してインライン検索でPATHを検索したものです。このようにパスが:(コロン)で区切って設定されています。もちろんユーザー側で、必要なパスを追記することもよく行われます。

PATH=/home/user/bin:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

LANG

ロケール (自然言語、通貨単位、日付の書式等の組み合わせ) を設定ししています。非常に多くのアプリケーションがこの環境変数を参照しています。この変数には ja_JP.UTF-8 を設定することがほとんどです。かつては ja_JP.eucJP が主流でした。ja_JP の部分がロケールの名前です

現在の環境を見るとやはり

user@Dimension-2400C:~$ echo $LANG
ja_JP.UTF-8

となっています。

Lubuntu 文字コードと変換・検出

現在、私はほぼ99%Lubuntuを使っているのですが、直接プリンタにはつながっていません。
一度、sambaを使ったプリンタのネットワーク共有を行ったのですが、その後Windows側でプリンタを認識しない不具合が続出して、現在では、プリンタ共有は中止しています。いまだ原因不明です。
文書の印刷が必要な時は、息子の使っているWindows10機で共有ファイル経由で印刷しています。
PDFや画像の時はそのまま印刷できるのですが、テキスト文書の場合、Windows10側でTeraPadというフリーのテキストエディタを使って開いて印刷します。TeraPadは動作も軽く文字コード・改行コードも自動で認識してくれるので重宝します。この文字コードと改行コードですが、デフォルトでLubuntu側では、文字コードがUTF-8、改行コードがLFで、Windows10側では、文字コードがShift-JIS、改行コードがCR+LFになっています。
ですので、Lubuntu側で普通に作ったテキストを、Windows側のノートパッドで開けると、改行がなくなっているような状態になってしまいます。そこで、TeraPadで開くとそのまま印刷できます。

それでは、文字コードにどのようなものがあるか概観してみます。

ASCIIコード

いろんな文字コードの基礎となっているコードで、キーボード上の「数字」「アルファベット」「記号」を1バイトで表現しています。他に改行コード(LF、CR)やタブ(HT)、制御コードのNULLヤBSなども含んでいます。

Shift-JIS

ASCIIコードに日本語の文字を加えたものです。半角カタカナは1バイトで表現し、その他の全角文字は2バイトで表現されています。
外字領域という未使用の領域があり、OSメーカーやベンダーが独自の文字を設定しています。このようにShift-JISを拡張したものに「M5932」があり、日本語のWindowsなどに使われています。

UTF-8

ASCIIコードに世界中の文字を加えたものです。ASCIIコード以外の文字は2〜8バイトで表現され、日本語の文字は、3バイトで表現されています。
世界中のソフトウエアの多くが、対応していて、PC界の共通語とも言えます。

EUC-JP

「Extended UNIX Code Packed Format for Japanese」の略です。日本語以外にも多言語対応していて、EUC-KR(韓国語)、EUC-CN(簡体中国語)などもあります。

他にもいろいろありますが、古い記事ですが以下のグラフが示すように、UTF−8が共通語みたいな感じになっています。

https://googleblog.blogspot.jp/2010/01/unicode-nearing-50-of-web.html

unicode

iconvコマンド(文字コードを変換して出力する)

iconvコマンドは、(入力ファイルまたは)標準入力を指定された文字コードに変換して標準出力に出力します。

使用構文 iconv -f 入力元文字コード -t 出力文字コード 入力ファイル

次の例では実際に、キーボードから入力した文が出力文字コードをShift-JISに変換してsiftjis.txtに出力します。catコマンドでsiftjis.txtをみて、文字化けするか確認してみます。

例user@Dimension-2400C:~/test$ iconv -t Shift-JIS >siftjis.txt
これから入力する文字は
文字化けして読めないと思われます
それでは確認してみます
user@Dimension-2400C:~/test$ cat siftjis.txt
���ꂩ�����͂��镶����
�����������ēǂ߂Ȃ��Ǝv�����܂�
�����ł͊m�F���Ă݂܂�
user@Dimension-2400C:~/test$ rm siftjis.txt
user@Dimension-2400C:~/test$

上のように文字化けしました。

nkfコマンド(文字コードを自動認識して変換、表示する)

nkfコマンドは、文字コードをオプションで指定した文字コードに変換します。

-e EUCコードに変換
-s シフトJISコードに変換
-w UTF-8コードに変換

例として、標準入力をsiftjis.txtにシフトJISコードで保存して、catコマンドで文字化けしているのを確認後、UTF-8に変換して正常に読めるのを確認します。

user@Dimension-2400C:~/test$ nkf -s >siftjis.txt
これから、シフトJISに 変換後、UTF-8に変換して、正常に読めるか確認します。
user@Dimension-2400C:~/test$ cat siftjis.txt
���ꂩ��JI�ϊ����AUTF-8�ɕϊ����āA�����ɓǂ߂邩�m�F���܂��B
user@Dimension-2400C:~/test$ nkf -w siftjis.txt | cat
これからJI変換後、UTF-8に変換して、正常に読めるか確認します。
user@Dimension-2400C:~/test$

上の実行例では、なぜか、正常にUTF-8に変換されていません。バグでしょうか?
試しに、iconvコマンドで変換してみます。

user@Dimension-2400C:~/test$ iconv -t UTF8 siftjis.txt | cat
iconv: 位置 0 に不正な入力シーケンスがあります
user@Dimension-2400C:~/test$ iconv -f Shift-JIS -t UTF8 siftjis.txt | cat
これからJI変換後、UTF-8に変換して、正常に読めるか確認します。
user@Dimension-2400C:~/test$

バグではなく、標準入力からファイルを作る時に問題があったようです。
加えて、iconvコマンドでは、入力の文字コードが、Shift-JISの場合それを指定してあげる必要があるようです。もう一度再現してみます。

ser@Dimension-2400C:~/test$ nkf -s >siftjis.txt
これから、シフトJISに 変換後、UTF−8に変換して正常に読めるか確認します。
user@Dimension-2400C:~/test$ nkf -w siftjis.txt | cat
これから、シフトJI変換後、UTF−8に変換して正常に読めるか確認します。
user@Dimension-2400C:~/test$

また、表示通りではありませんが、原因として考えられるのは、私がキーボードから入力する時に打ちなおしたところがおかしくなっているようです。今度は、エディタで編集したものを貼り付けて入力します。

user@Dimension-2400C:~/test$ nkf -s >siftjis.txt
これから、シフトJISに 変換後、UTF−8に変換して正常に読めるか確認します。
user@Dimension-2400C:~/test$ nkf -w siftjis.txt | cat
これから、シフトJISに 変換後、UTF−8に変換して正常に読めるか確認します。
user@Dimension-2400C:~/test$

今度は、うまく行っています。これで、標準入力の場合、打ち間違えると、表示上と違ったものが入力される可能性があることがわかりました。

文字コードの確認

nkfコマンドでは、また、文字コードの確認もできます。

nkf -g 確認するファイルパス

で確認できます。

以下実行例です。

user@Dimension-2400C:~/test$ nkf -g siftjis.txt
Shift_JIS

Lubuntu パイプによるコマンドの結合・フィルタとして機能するコマンド

 

パイプとは、コマンドの標準出力を次のコマンドに渡す処理のことをいいます。
パイプを使った処理のことを「パイプライン処理」といいます。
パイプライン処理は、縦線の記号「|」を使います。
記号「|」は、Shiftキーを押しながら、¥キーを押すと入力できます。

実際に使用してみます。
まず、catコマンドでtestfile1に、キーボードから入力した文字をリダイレクトさせます。

user@Dimension-2400C:~$ cat >>testfile1
abc
def
ghi
jkl

下の例では、catコマンドで、標準出力に書き出すところを、パイプを使ってsortコマンドに渡して、逆順(-r オプション)で表示しています。

user@Dimension-2400C:~$ cat testfile1 | sort -r
jkl
ghi
def
abc

上の例では、2つのコマンドを繋げていますが、3つでも、4つでも繋げることが出来ます。

フィルタとして動作するコマンド

フィルタとしての機能を持つコマンドとして
sort、head、tail、uniq、cut、grep、sed
を見ていきます。

sortコマンド(テキストをソート、マージ)

sortコマンドは、上記のようにファイルを行単位でソート(並べ替え)をできますが、次の例のように、ソート済みファイルとしてマージすることも出来ます。マージには、-mオプションを使います。

user@Dimension-2400C:~$ cat >testfile1
1
3
5
7
9
user@Dimension-2400C:~$ cat >testfile2
2
4
6
8
10
user@Dimension-2400C:~$ sort -nm testfile1 testfile2 >testfile3
user@Dimension-2400C:~$ cat testfile3
1
2
3
4
5
6
7
8
9
10

-nオプションは数字順に並べ替えです。

headコマンド(先頭行を表示する)

デフォルトでは先頭から10行表示します。

-n オプションで表示する行数を指定できます。

例 testfile3 の先頭3行だけを表示します。

user@Dimension-2400C:~$ cat testfile3
1
2
3
4
5
6
7
8
9
10
user@Dimension-2400C:~$ head -n 3 testfile3
1
2
3

tailコマンド(末尾を表示)

デフォルトでは末尾から10行を表示します。

-n オプションで表示する行数を指定できます。

例 testfile3 の末尾3行だけを表示します。

user@Dimension-2400C:~$ cat testfile3
1
2
3
4
5
6
7
8
9
10
user@Dimension-2400C:~$ tail -n 3 testfile3
8
9
10

uniq(ソート済みのファイルから重複した行を削除する)

使い方の例

user@Dimension-2400C:~$ cat >testfile3
1
3
5
7
9
2
4
6
8
10
3
5
7
9
user@Dimension-2400C:~$ cat testfile3 | sort -n | uniq
1
2
3
4
5
6
7
8
9
10

cutコマンド(各行から指定したフィールドを出力)

-c オプションで指定した位置の文字だけ表示できます。

(例)4から7文字を表示する場合

user@Dimension-2400C:~$ cat >testfile1
id 0001 agent_A
id 0002 agent_B
id 0003 agent_c
user@Dimension-2400C:~$ cut -c 4-7 testfile1
0001
0002
0003

-f オプションで指定したフィールドを表示できます。
-d オプションで、区切り文字を指定できます。デフォルトでは、タブになっています。

(例)スペース区切りの2番目~3番目のフィールドを表示

user@Dimension-2400C:~$ cat testfile1
id 0001 agent_A
id 0002 agent_B
id 0003 agent_c
user@Dimension-2400C:~$ cut -f 2-3 -d’ ‘ testfile1
0001 agent_A
0002 agent_B
0003 agent_c

grepコマンド(パターンにマッチする行を表示)

(例)カレントディレクトリでagentにマッチする行を表示

user@Dimension-2400C:~$ grep agent* *
grep: Desktop: ディレクトリです
grep: Documents: ディレクトリです
grep: Downloads: ディレクトリです
grep: Dropbox: ディレクトリです
grep: Music: ディレクトリです
grep: Pictures: ディレクトリです
grep: Public: ディレクトリです
grep: Templates: ディレクトリです
grep: Videos: ディレクトリです
grep: delorio_video: ディレクトリです
grep: test: ディレクトリです
grep: testatesaki: ディレクトリです
testfile1:id 0001 agent_A
testfile1:id 0002 agent_B
testfile1:id 0003 agent_c

上記処理の概要は、
$ grep agent* *で、カレントディレクトリのすべてのファイルに対してagent*にマッチする文字列を検索。
結果、ファイル名:マッチ行内容 という形で表示されています。

また、初心者の私のわからないことは、このgrepコマンドをカレントディレクトリで実行すると、どの階層まで探してくれるのかと言った疑問がわきます。

実際に、実験してみます。

user@Dimension-2400C:~$ cd test
user@Dimension-2400C:~/test$ tree
.

0 directories, 0 files
user@Dimension-2400C:~/test$ mkdir test
user@Dimension-2400C:~/test$ cd test
user@Dimension-2400C:~/test/test$ mkdir test
user@Dimension-2400C:~/test/test$ cd test
user@Dimension-2400C:~/test/test/test$ cat >magofile1
id 0001 type a name youko
id 0002 type b name kaori
id 0003 type c name hiroko
user@Dimension-2400C:~/test/test/test$ cp magofile1 magofile2
user@Dimension-2400C:~/test/test/test$ cp * ~/test/test
user@Dimension-2400C:~/test/test/test$ cp * ~/test
user@Dimension-2400C:~/test/test/test$ cd ~/test
user@Dimension-2400C:~/test$ tree
.├── magofile1
├── magofile2
├── siftjis.txt
└── test
├── kofile1
├── kofile2
└── test
├── magofile1
└── magofile2
2 directories, 6 files

user@Dimension-2400C:~/test$ grep name* *
magofile1:id 0001 type a name youko
magofile1:id 0002 type b name kaori
magofile1:id 0003 type c name hiroko
magofile2:id 0001 type a name youko
magofile2:id 0002 type b name kaori
magofile2:id 0003 type c name hiroko
grep: test: ディレクトリです
user@Dimension-2400C:~/test$

以上のように、カレントディレクトリ直下のファイルをマッチングしてくれます。

以下の例のように、-Rオプションをつけると配下のすべてのディレクトリ内を再帰的にマッチングしてくれます。

user@Dimension-2400C:~/test$ grep -R name* *
magofile1:id 0001 type a name youko
magofile1:id 0002 type b name kaori
magofile1:id 0003 type c name hiroko
magofile2:id 0001 type a name youko
magofile2:id 0002 type b name kaori
magofile2:id 0003 type c name hiroko
test/magofile2:id 0001 type a name youko
test/magofile2:id 0002 type b name kaori
test/magofile2:id 0003 type c name hiroko
test/magofile1:id 0001 type a name youko
test/magofile1:id 0002 type b name kaori
test/magofile1:id 0003 type c name hiroko
test/test/magofile2:id 0001 type a name youko
test/test/magofile2:id 0002 type b name kaori
test/test/magofile2:id 0003 type c name hiroko
test/test/magofile1:id 0001 type a name youko
test/test/magofile1:id 0002 type b name kaori
test/test/magofile1:id 0003 type c name hiroko

この-Rオプションですが他にも、lsコマンドなどでも再帰的動作をしてくれます。
どのコマンドが再帰的に動作してくれるかは、man コマンド名で検索し、文中にrecursiveという表現があるかどうかで判断出来ます。
それにしても、疑問なのは、ノーオプションで*(ワイルドカード)を使った時に、カレントディレクトリ直下まで動作するコマンドと子ディレクトリまで動作するコマンドがありどこで区別できるのかと言ったことです。例えば、findコマンドの場合、配下のすべてのディレクトリまで再帰的に検索マッチングしてくれます。今それについて調査中です。

sed(文字列の置換,行の削除を行う)

文字列の置換の例

user@Dimension-2400C:~$ cat testfile1
id 0001 agent_A
id 0002 agent_B
id 0003 agent_c
user@Dimension-2400C:~$ sed -e “s/agent_/はらほれ ふん/g” testfile1
id 0001 はらほれ ふんA
id 0002 はらほれ ふんB
id 0003 はらほれ ふんc

注意すべきなのは
$ sed -e “s/agent_/はらほれ ふん/g” *
で「agent」を「はらほれ ふん」に変換していますが、ストリーム上で変換されているだけで、それをファイルに書き出さないと保存されないという事です。

行の削除の例

user@Dimension-2400C:~$ cat testfile1
id 0001 agent_A
id 0002 agent_B
id 0003 agent_c
user@Dimension-2400C:~$ sed -e “1,2d” testfile1
id 0003 agent_c

上の例ではtestfile1の1行目から2行目が削除されています。
これも、あくまでストリーム上のことで入力ファイルは変更されていないことに注意しましょう。

Lubuntu 標準入出力のリダイレクト

標準出力のリダイレクト

標準出力のリダイレクトとは、標準出力や、標準エラー出力の出力先を変更することを意味しています。
リダイレクトは、標準出力をファイルに出力するときに使用することが多いです。
以下の例では、カレントディレクトリのファイルの拡張子がoで始まる4桁のファイルのみの情報をfindコマンドを使って、workfileに書き込んでいます。この時、標準出力のみがリダイレクトされ標準エラー出力はリダイレクトされていません。(画面に表示される)

(リダイレクト例1)
user@Dimension-2400C:~$ find -type f -name ‘*.o???’ > workfile
find: `./.gconf/desktop’: 許可がありません
user@Dimension-2400C:~$ cat workfile
./delorio_video/Amanhã é Sábado.opus
./delorio_video/Se For Pra Mentir.opus
./Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
./Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
./Music/Roberta Sa/Delirio/Boca em Boca.opus
./Music/Roberta Sa/Delirio/CUm Só Lugar.opus
./Music/Roberta Sa/Delirio/Última Forma.opus
./Music/Roberta Sa/Delirio/Delírio.opus
./Music/Roberta Sa/Delirio/Me Erra.opus
./Music/Roberta Sa/Delirio/Um Só Lugar.opus
./Music/Roberta Sa/Delirio/Covardia.opus
./Music/Roberta Sa/Delirio/Meu Novo Ilê.opus
記号 > を使って、>の右側にリダイレクト先を指定しています。

注意が必要なのは、>でリダイレクトすると、宛先のファイルに内容があった場合、上書きされて、消されてしまうということです。

ファイルの末尾に追記する場合は、>> の記号を用います。

上の例の場合、出力の標準出力をリダイレクトしていますが、標準出力と標準エラー出力を分けてリダイレクトできます。
以下の例では、標準出力は画面、標準エラー出力は、workfileに出力します。

(リダイレクト例2)
user@Dimension-2400C:~$ find -type f -name ‘*.o???’ 2> workfile
./delorio_video/Amanhã é Sábado.opus
./delorio_video/Se For Pra Mentir.opus
./Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
./Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
./Music/Roberta Sa/Delirio/Boca em Boca.opus
./Music/Roberta Sa/Delirio/CUm Só Lugar.opus
./Music/Roberta Sa/Delirio/Última Forma.opus
./Music/Roberta Sa/Delirio/Delírio.opus
./Music/Roberta Sa/Delirio/Me Erra.opus
./Music/Roberta Sa/Delirio/Um Só Lugar.opus
./Music/Roberta Sa/Delirio/Covardia.opus
./Music/Roberta Sa/Delirio/Meu Novo Ilê.opus
user@Dimension-2400C:~$ cat workfile
find: `./.gconf/desktop’: 許可がありません

上の2の数字のことをファイルディスクリプタといい、1は標準出力、2は標準エラー出力になっています。

標準エラー出力を含めてリダイレクトする

(リダイレクト例3)
user@Dimension-2400C:~$ find -type f -name ‘*.o???’ > workfile 2> &1
bash: 予期しないトークン `&’ 周辺に構文エラーがあります
user@Dimension-2400C:~$ find -type f -name ‘*.o???’ > workfile 2>&1
user@Dimension-2400C:~$ cat workfile
./delorio_video/Amanhã é Sábado.opus
./delorio_video/Se For Pra Mentir.opus
find: `./.gconf/desktop’: 許可がありません
./Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
./Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
./Music/Roberta Sa/Delirio/Boca em Boca.opus
./Music/Roberta Sa/Delirio/CUm Só Lugar.opus
./Music/Roberta Sa/Delirio/Última Forma.opus
./Music/Roberta Sa/Delirio/Delírio.opus
./Music/Roberta Sa/Delirio/Me Erra.opus
./Music/Roberta Sa/Delirio/Um Só Lugar.opus
./Music/Roberta Sa/Delirio/Covardia.opus
./Music/Roberta Sa/Delirio/Meu Novo Ilê.opus
例3のように、2>&1を後ろに付けます。2>&1で標準エラー出力を標準出力にリダイレクトするという意味になります。1回めの実行で失敗しているように、&周辺にスペースが入るとエラーになるようです。

ファイルディスクリプタ

プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子のことを、ファイルディスクリプタといいます。

通常は、

0:標準入力(stdin)
1:標準出力(stdout)、
2:標準エラー出力(stderr)

の3つは、OSで最初に割り当てられていて、以降にプログラムがファイルをオープンするごとに、3から順番に割り当てることができます。

nullデバイスを利用して出力を捨てる

/dev/null(nullデバイス)を出力先にして、出力を捨てることが出来ます。下の例では標準エラー出力を捨てています。nullデバイスは、何もしないデバイスとして存在し、ゴミ箱とかブラックホールとかいう愛称で呼ばれています。

(リダイレクト例4)
user@Dimension-2400C:~$ find -type f -name ‘*.o???’ 2> /dev/null
./delorio_video/Amanhã é Sábado.opus
./delorio_video/Se For Pra Mentir.opus
./Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
./Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
./Music/Roberta Sa/Delirio/Boca em Boca.opus
./Music/Roberta Sa/Delirio/CUm Só Lugar.opus
./Music/Roberta Sa/Delirio/Última Forma.opus
./Music/Roberta Sa/Delirio/Delírio.opus
./Music/Roberta Sa/Delirio/Me Erra.opus
./Music/Roberta Sa/Delirio/Um Só Lugar.opus
./Music/Roberta Sa/Delirio/Covardia.opus
./Music/Roberta Sa/Delirio/Meu Novo Ilê.opus

標準入力のリダイレクトと入出力ファイルの同時指定

catコマンドは、パラメータを与えなければ、標準入力の入力(キーボード入力)を待ちます。
以下に、端末から入力した内容をnyuuryoku.txtにリダイレクトする例を実行します。

(リダイレクト例5)
user@Dimension-2400C
:~$ cat >>nyuuryoku.txt
korerano mojiretuga
sonomama fairuni kakikomaremasu
owaruniha ctrl+d wo
taipusimasuuser@Dimension-2400C:~$ cat nyuuryoku.txt
korerano mojiretuga
sonomama fairuni kakikomaremasu
owaruniha ctrl+d wo
taipusimasuuser@Dimension-2400C:~$ cat <workfile
./delorio_video/Amanhã é Sábado.opus
./delorio_video/Se For Pra Mentir.opus
find: `./.gconf/desktop’: 許可がありません
./Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
./Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
./Music/Roberta Sa/Delirio/Boca em Boca.opus
./Music/Roberta Sa/Delirio/CUm Só Lugar.opus
./Music/Roberta Sa/Delirio/Última Forma.opus
./Music/Roberta Sa/Delirio/Delírio.opus
./Music/Roberta Sa/Delirio/Me Erra.opus
./Music/Roberta Sa/Delirio/Um Só Lugar.opus
./Music/Roberta Sa/Delirio/Covardia.opus
./Music/Roberta Sa/Delirio/Meu Novo Ilê.opus
user@Dimension-2400C:~$ cat <workfile >>nyuuryoku.txt
user@Dimension-2400C:~$ cat nyuuryoku.txt
korerano mojiretuga
sonomama fairuni kakikomaremasu
owaruniha ctrl+d wo
taipusimasu./delorio_video/Amanhã é Sábado.opus
./delorio_video/Se For Pra Mentir.opus
find: `./.gconf/desktop’: 許可がありません
./Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
./Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
./Music/Roberta Sa/Delirio/Boca em Boca.opus
./Music/Roberta Sa/Delirio/CUm Só Lugar.opus
./Music/Roberta Sa/Delirio/Última Forma.opus
./Music/Roberta Sa/Delirio/Delírio.opus
./Music/Roberta Sa/Delirio/Me Erra.opus
./Music/Roberta Sa/Delirio/Um Só Lugar.opus
./Music/Roberta Sa/Delirio/Covardia.opus
./Music/Roberta Sa/Delirio/Meu Novo Ilê.opus
user@Dimension-2400C:~$

上の例で、$ cat <workfile というふうに標準入力をファイルにリダイレクトすることが出来ます。
さらに、$ cat <workfile >>nyuuryoku.txt のように入力と出力のファイルを同時に指定することも出来ます。

※※ここで、注意が必要なのは、入力ファイルと出力ファイル同じファイルにすると、空のファイルになってしまうということです。※※

Lubuntu ワイルドカードを利用する

シェルにはワイルドカードという,ファイル名を補完する機能があります. ワイルドカードを使ってパターンを指定し,長いファイル名を短いタイプでマッチさせたり,複数のファイルにマッチさせたりすることができます. これをシェルのファイル名展開ともいいます.

ファイルを指定するときに使えるワイルドカードには次のようなものがあります。

*(アスタリスク) 任意の文字列(文字がなくてもいい)
?       任意の1文字
[文字列]       []に含まれている文字の内どれか一文字
[!文字列]      []に含まれない1文字
~(チルダ)   ユーザーのホームディレクトリの絶対パス

以上を組み合わせた使用例を書きます。

*.txt*      拡張子がtxtであるすべてのファイル
*Roberta*   文字列Robertaを含むすべてのファイル
*.[opq]*   拡張子がopqのいずれかの文字で始まるすべてのファイル
*.[o-q]*    拡張子がoからqのどれかの文字ではじまるすべてのファイル
[a-zA-Z]*   ファイル名がアルファベットで始まるすべてのファイル
*[0-9]*   ファイル名に数字が含まれているすべてのファイル
[!0-9]*   ファイル名が数字で始まらないすべてのファイル
*.???    拡張子が3文字のすべてのファイル
~/*     ホームディレクトリにあるすべてのファイル
*.o*        拡張子がOで始まるすべてのファイル

“Music/Roberta Sa/”*  ディレクトリ”Music/Roberta Sa/”にあるすべてのファイル※

※ディレクトリ名にスペースが含まれる場合”(ダブルクオーテーションマーク)で囲ってあげることが必要です。ワイルドカード文字は、ダブルクォーテーションの外側に記述します。

lsコマンドでのワイルドカードの動作

lsコマンドでワイルドカードを使うと、子ディレクトリの中身までリストアップしてくれます。

以下実行例です。

user@Dimension-2400C:~$ ls -l “Music/Roberta Sa/”
合計 4
drwxrwxr-x 2 user user 4096 5月 14 20:56 Delirio
user@Dimension-2400C:~$ ls -l “Music/Roberta Sa/”*
合計 41832
-rw-rw-r– 1 user user 3804154 5月 6 09:58 Boca em Boca.opus
-rw-rw-r– 1 user user 3285832 5月 6 09:45 CUm Só Lugar.opus
-rw-rw-r– 1 user user 5584986 5月 6 09:17 Covardia.opus
-rw-rw-r– 1 user user 7018187 5月 6 09:26 Delírio(Selvagem Remix).opus
-rw-rw-r– 1 user user 3092990 5月 6 09:32 Delírio.opus
-rw-rw-r– 1 user user 4391111 5月 6 09:33 Me Erra.opus
-rw-rw-r– 1 user user 3608977 5月 6 09:39 Meu Novo Ilê.opus
-rw-rw-r– 1 user user 3881895 5月 6 09:43 Não Posso Esconder o que o Amor Me Faz.opus
-rw-rw-r– 1 user user 3285832 5月 6 09:48 Um Só Lugar.opus
-rw-rw-r– 1 user user 4856836 5月 6 09:49 Última Forma.opus

上の実行例で、一回目のワイルドカードを付けない実行の場合、子ディレクトリの情報をリストしてくれます。
2回めのワイルドカードを付けた実行の場合、子ディレクトリの中のファイルをリストしてくれます。

Findコマンドにワイルドカードを使った検索

ホームディレクトリで拡張子がOで始まり4文字のファイルを検索してみます。

user@Dimension-2400C:~$ find ~ -name “*.o???”
/home/user/delorio_video/Amanhã é Sábado.opus
/home/user/delorio_video/Se For Pra Mentir.opus
find: `/home/user/.gconf/desktop’: 許可がありません
/home/user/Music/Roberta Sa/Delirio/Delírio(Selvagem Remix).opus
/home/user/Music/Roberta Sa/Delirio/Não Posso Esconder o que o Amor Me Faz.opus
/home/user/Music/Roberta Sa/Delirio/Boca em Boca.opus
/home/user/Music/Roberta Sa/Delirio/CUm Só Lugar.opus
/home/user/Music/Roberta Sa/Delirio/Última Forma.opus
/home/user/Music/Roberta Sa/Delirio/Delírio.opus
/home/user/Music/Roberta Sa/Delirio/Me Erra.opus
/home/user/Music/Roberta Sa/Delirio/Um Só Lugar.opus
/home/user/Music/Roberta Sa/Delirio/Covardia.opus
/home/user/Music/Roberta Sa/Delirio/Meu Novo Ilê.opus

初心者の心配

初心者の私は、こんなことを心配します。

「rm * と間違えて実行してしまえば、ファイルがみんな消えてしまうのではないか?」

そこで、テストディレクトリを作りどういうことが起こるのか検証してみます。

treeコマンドという、ツリー状に、ディレクトリとファイルを表示してくれるコマンドがあるので、それを使って作成したディレクトリの中身を表示します。

user@Dimension-2400C:~/test$ tree
プログラム ‘tree’ はまだインストールされていません。 次のように入力することでインストールできます:
sudo apt install tree
user@Dimension-2400C:~/test$ sudo apt install tree
[sudo] user のパスワード:
パッケージリストを読み込んでいます… 完了
依存関係ツリーを作成しています
状態情報を読み取っています… 完了
・・・
中略
・・・
user@Dimension-2400C:~/test$ tree
.
├── kotest
│   ├── kotest1
│   ├── kotest2
│   └── magotest
│   ├── himagotest
│   │   ├── himagotest1
│   │   └── himagotest2
│   ├── magotest1
│   └── magotest2
├── test1
└── test2

3 directories, 8 files

以上のようにデフォルトでは、インストールされていないのでインストールしました。
上記のように曾孫ディレクトリまで作成しました。

それでは、rm * を実効。

user@Dimension-2400C:~/test$ rm *
rm: ‘kotest’ を削除できません: ディレクトリです
user@Dimension-2400C:~/test$ tree
.
└── kotest
├── kotest1
├── kotest2
└── magotest
├── himagotest
│   ├── himagotest1
│   └── himagotest2
├── magotest1
└── magotest2

3 directories, 6 files

結果からカレントディレクトリ直下のファイルがすべて削除されることが判明(ここでは、test1、test2が削除されている)。
lsコマンドのように、子ディレクトリまでは、動作が行かないことがわかりました。

ついでに、

cp * デイレクトリ1 は、カレントディレクトリのファイルのみが、ディレクトリ1にコピーされました。(ディレクトリはコピーされない。)

mv * ディレクトリ1 は、カレントディレクトリ配下のすべて(ディレクトリを含む)がそのままディレクトリ1に移動しました。

コマンド名入力時の自動補完

コマンド名を入力するとき、最初の3文字だけ入力して、Tabキーを押すと自動補完してくれます。