バッシュのためのもう一つのカンニングペーパー


基礎


どこかから始まる.注意してください、いくつかのコマンドはbash 4を必要とするかもしれません(大部分のスニペットはbash 3のためです).

bashは頭字語です


bashは「ボーン・トゥ・シェル」を意味します.実際、bashは1979年に最初にリリースされた古いボーンシェルに取って代わった.

bashは" Unix Versal "スクリプト言語です


bashは、それがあなたの個人的な使用のために、サーバーのメンテナンス、またはdevopsのアクションのためであるかどうか様々なタスクを自動化するために学ぶことができる狂った良い言語です.bashスクリプトは、プレーンテキストファイルで一連のコマンドラインを書くことから成るかもしれません.
端末にこれらのコマンドを入力することもできます.などの既存のコマンドを使用することができますgrep , sed , find しかし、サードパーティ製のライブラリから追加のコマンドをインストールしている可能性があります.
しかし、多くの場合は、Gitをすることができますし、1つのマシンから別のマシンに転送または複数のサーバーで実行するファイル内のすべての命令をグループ化するために便利です.bashスクリプトは通常、以下のように実行できます.
bash myscript
また、スクリプトを実行可能にして実行できます.
chmod +x myscript && ./myscript

bashはshではない!


bashはほとんどのshスクリプトを実行することができます(構文はかなり似ています)、shはすべてのbashコマンドを処理できません.
以下のコマンドラインはおそらく動作しますが、少し誤解を招く可能性があります.
bash mysh.sh
sh myscript

船歌を忘れるな


それは#! bashファイルの先頭にあります."Bang "は感嘆符"!"
#!/usr/bin/env bash
上記の線は全く装飾的ではありません!スクリプトはbashインタプリタの絶対パスにリンクします./usr/bin/env は通常、ユーザーの$ path変数に設定された実行可能ファイルをグラブするので、スマートな選択です.

コメントを書く


使用する# :
# comment

変数


変数は宣言し、使用し、bashで操作するのは簡単です.

組み込み変数(完全なリストではない)


echo "$1 $2" # positional arguments passed one by one, e.g., bash myscript arg1 arg2
echo "$#" # number of arguments passed
echo "$@" # all arguments passed
echo "You are here: $PWD" # $PWD is the current path

新しい変数の割り当て


変数を= サインしないでください.
MyVar="My string"
MyArray=(all in one)

変数の使用


宣言された変数を$ サイン
echo $Variable
echo "This is my var: $Variable" # double quotes are required for interpolation
echo "${MyArray[@]:0:3}" # "all in one", because it prints 3 elements starting from the first (0)

# Be careful the following does not display a value
echo ${#MyArray[2]} # "3" as there are 3 chars in the third element of the array, which is the word "one"

変数の変更


宣言された変数は、{} :
MyVar="My variable"
# Length
echo ${#MyVar}

# Substitution
echo ${MyVar//a/O} # "My vOriOble"

# Expansion
echo ${!BASH@} # all variable names than begin with "BASH"
echo ${!BASH*} # all variable names than begin with "BASH"

# Removals
MyFile="list.txt"
echo ${MyFile%.*} # the filename without extension
echo ${MyFile##*.} # the file's extension

# Default value
echo ${AnotherOne:-"Another one"} # displays "Another one" even if AnotherOne is not defined

辞書


declare -A Movies

Movies[title]="The Dark Knight Rises"
Movies[bestActress]="Anne Hathaway"
Movies[director]="Christopher Nolan"

printf

printf プリフォーマットされたテキストを印刷するCのような方法です.これは、より簡単な方法よりも高度な機能を提供しますecho . これは引数としてフォーマットとパラメータを取り、フォーマットされたテキストを出力します.
たとえば、1つの行で型といくつかの書式指定オプションを指定できます.
printf "%s\n" "Learn it" "Zip it" "Bash it" # it prints 3 lines
printf "%.*f\n" 2 3.1415926 # prints 3.14

ループ&ループ


For


for i in "${MyArray[@]}"; do
    echo "$i"
done
文字列でも動作します.
MyString="First Second Third"
for n in $MyString
do
   echo "$n line"
done


while [ true ]
do
    echo "We loop"
    break
done

ハンディレンジ


echo {1..7} # 1 2 3 4 5 6 7
echo {a..g} # a b c d e f g

まで


until [ $counter == 111 ]
do
    echo "Number is: $((counter++))"
done

ユーザ入力の取得


echo "6x7?"
read answer
echo answer # hopefully 42 but can be anything the user wants

条件文


if [[ CONDITION1 || CONDITION2 ]]
then
    # code
elif [[ CONDITION3 && CONDITION4 ]]
then
    # code
else
    # code
fi
また、case文を使用することもできます.
case $COLOR in

  Red)
    echo -n "red"
    ;;

  Blue | Green)
    echo -n "blue or green"
    ;;

  Yellow | "Sunny" | "Gold" | "Fire")
    echo -n "Yellow"
    ;;

  *)
    echo -n "What?"
    ;;
esac

エラーと終了戦略


スクリプトの誤用を防ぐためにエラーを発生させることができます.

コマンドが失敗した場合に直ちに終了する


#!/usr/bin/env bash
set -e

出口N


スクリプトを終了し、終了コードを指定できます.
#!/usr/bin/env bash
if [ CONDITION ]; then
    exit 0 # 0 1 2 3 ... N
fi
0は成功を示し、{ 1 , 2 , 3 , n }はエラーです.

テストエラー


# $? is the exit status of last command
if [[ $? -ne 0 ]] ; then
    echo "You failed!"
    exit 1
else
    echo "You are the best!"
fi

スクリプトのデバッグ


#!/usr/bin/env bash
set -x # set -n can also be used to check syntax errors
ARGS=("$@") # store all script args in a var
また、-x 端末のオプション
bash -x myscript

ファイルシステムとディレクトリ


などのすべての基本的なファイルシステムコマンドを使用することができますcp , rm , ls , mv or mkdir あなたのbashスクリプトで.
ファイルが実行前に実行可能かどうかを調べる
if [ ! -x "$PWD/myscript" ]; then
    echo "File is not executable!"
    exit 1
fi
用途-f ファイル-d ディレクトリ-e 存在のために、オプションのトンがあり、あなたも、シンボリックリンクをテストすることができます-L でファイルを比較する-nt より新しい-ot (古い)オプション.

もう少し高度な利用


ここでいくつかのヒント私はもう少し複雑な基本的なものより検討しています.

BASH構文の利点を活用する


bashは出力を高速に構築するのにとても便利です.特にブレース展開を使用します.
echo {1..10}{0,5}h # bash 3
echo {10..120..10}km # requires bash 4

関数定義


function test ()
{
    echo "$1 $2" # displays positional arguments passed to the function ("All" "In")
    return 0 # if you return a value, it !must be numerical!
}
test "All" "In"

スコープ


bashに変数を宣言する必要はありません.存在しない変数を呼び出すと、エラーはなく、空の値を取得しません.

環境変数


env varsはシステムレベルで定義されます.彼らは至る所に至る所に存在する.
リストを表示するにはprintenv :
printenv USER # if you don't specify a variable, all variables will be displayed

シェル変数


以下の割り当てはシェル変数を定義します:
TEST="My test"
あなたが直接機能の中で、スクリプト内の任意の場所でそれを使用することができます.ただし、export このような情報を送信するコマンドです.

ローカルキーワード


The local キーワードは関数の中でのみ使用できます:
function test ()
{
    local MyVar="My string" # local variable
}
test
ローカル変数をエクスポートできません.

ベストプラクティス


一般的に、ローカル変数と関数を使用する方が良いです.グローバル変数は意味を持って使用されるべきです.それは不必要な乗降と混乱を防ぐ.

コマンドの結果をループする


for r in $(ls $PWD)
do
    # task using the result of the command => r
    echo "$r"
done

関数の出力を使用する


function hello() {
    echo "Hello Ethan"
}

echo "This is the result of the function : $(hello)"

コマンドの結果を変数に保存する


Users=$(cat users.txt)

キャプチャはい/いいえ入力


read -p "Continue? [y/n]: " -n 1 -r
echo # extra line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    echo "ok"
elif [[ $REPLY =~ ^[Nn]$ ]]
then
    echo "Too bad!"
else
    echo "Sorry, I did not understand your answer :("
fi

キャプチャユーザーの選択


次のbashコードはユーザーに選択を促し、アンサーをキャプチャします.
select w in "zsh" "bash" "powershell" 
do
  echo "You prefer $w"
  break  
done

エイリアスとオーバーライドコマンド


特別なエイリアスを作成できます.
alias lz='ls -alh'
既存のコマンドを再定義するだけでもオーバーライドできます.

連鎖コマンド


wget -O /tmp/logo.jpg 'https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png' && echo "echo only if the first hand is true"
wget -O /tmp/logo2.jpg 'https//example.com/logo.jpg' || echo "echo only if the first hand is wrong"
wget -O tmp/logo3.jpg 'https//example.com/logo.jpg' ; echo "echo whatever happens"

ハードモード


ここではbashのいくつかの高度な概念が役に立つかもしれません.

コマンド実行


sudo !!

リダイレクト、stderr、stdout


COMMAND > out.txt   # write in out.txt 
COMMAND >> out.txt  # append in out.txt 
COMMAND 2> test.log # stderr to test.log
COMMAND 2>&1        # stderr to stdout
COMMAND &>/dev/null # stdout and stderr to (null)
置換COMMAND あなたのコマンドで.

それはトラップです!


The trap コマンドはエラーの高度なアプローチです.それを理解する鍵は、他の言語で知っているかもしれない例外と類似した概念について忘れることです.
アイデアは特定の条件でのみ実行することです.
#!/usr/bin/env bash

trap 'catch' EXIT

catch() {
  echo "Exit game!"
}

echo "ok"
echo "---"

exit 0
メッセージ“終了ゲーム!”のみ表示されますexit 0 最後に.
より実用的には、そのような使用法を見ることは珍しくありません.
#!/usr/bin/env bash

trap "rm /tmp/scan.txt" EXIT

スクリプトスクリプト内でスクリプトを実行する


使用するsource コマンド
#!/usr/bin/env bash

source ./otherScript

部分殻


A subshell is a separate instance of the command processor. A shell script can itself launch subprocesses. These subshells let the script do parallel processing, in effect executing multiple subtasks simultaneously.


Source: tldp.org
つまり、括弧内で囲まれたコマンドは副シェルで実行される.それは部分的にはexport 環境変数をサブプロセスに渡すコマンド.
あなたは時々「フォーク」という言葉を読んだが、それは同じ考えだ.

ピルフェイル


次のように、より高度なエラー処理として使用できます.
#!/usr/bin/env bash

set -eu # u is to exit if using undefined variables
set -o pipefail
上記の設定されたコマンドは「エラーモード」を有効にするだけでなく、パイプラインでのエラーが全く起こらないようにします-o pipefail オプション.

私のお気に入りのトリック


以下のコマンドは純粋なbashスクリプトよりもUNIXであるかもしれませんが、それは完全にオフのトピックではありません🤞🏻.

バッシュを使う


サードパーティ製のソリューションをターミナルプロンプトやZSHを使用してインストールすることができます.ジャストタイプ:
bash
Enterキーを押すと、bashプロンプトが使用されます.それから、あなたはタイプman bash ヘルプを表示するには

使用


使えます\ 長いコマンドラインの最後に読みやすさを改善し、フォーカスを失うことはありません.

使用


nohup bash script &
上記のバックグラウンドでbashスクリプトを実行し、ハングアップシグナルをキャッチできます.

その他


私が頻繁に使用するいくつかのトリック:

現在のフォルダだけのサブディレクトリをリストする


SUBDIRS=$(ls -d */)
for sub in $SUBDIRS
do
    echo $sub
done

ファイルの名前の変更


mv /project/file.txt{,.bak} # rename file.txt.bak

リモートサーバー上でローカルbashスクリプトを実行する


ssh REMOTE_HOST 'bash -s' < myScript

重いファイルを見つける


find . -size +10M -print

複数のファイルをすばやく作成


次のように入力できます
touch {script1,script2,script3,script4,script5,script6,script7}
しかし、それはまだ少し退屈です.
touch script{1..7}

ハッカーのためのバッシュ


ハッカーは確かにバッシュだろう.Pythonは驚くほどペンテストのために便利ですが、bashはまた、多くのタスクを自動化することができます.これは、専門家が分析を高速化するカスタムbashスクリプトを作成するのは珍しいことではない.

ハロー・ワールド


繰り返し同じコマンドラインを繰り返す代わりに、特定のファイルにグループ化できます.ほとんどのセキュリティバイナリはそのように構築されています.
あなたはread コマンドを使用してスクリプトをより使いやすくするか、引数を渡すだけです.スクリプト名を挙げましょうscanning
#!/usr/bin/env bash

echo "Welcome aboard"
echo "What's the targeted IP?"
read TargetIp

if [[ ! $TargetIp ]]
    then echo "Missing targeted IP!"
    exit 1
fi

echo "What port do you want to scan?"
read PortNumber

if [[ ! $PortNumber ]]
    then echo "Missing port number!"
    exit 1
fi

nmap $TargetIp -p $PortNumber >> scan.txt # append results in scan.txt
その後、我々は実行することができますbash scanning . もちろん、NMAPの使用を楽にする既存のツールがあります、そして、それは非常に不完全な例です、しかし、あなたは考えを見ます.

エイリアシング


攻撃者は端末で高度なコマンドを使用する際にエイリアスを使用します.
alias whatsMyIp="echo $(ifconfig -a | grep broadcast | awk '{print $2}')"
whatsMyIp # IP local
ペンのテストディストリビューションは、より良い自動補完機能を持っているかもしれませんが、あなたは常にそのような最適化された環境では動作しませんので、エイリアスは多くの時間とエネルギーを節約することができます.

ハッキングバッシュ


ハッカーは他の言語のようにbashをハックできます.ジャストread this post by hacktricks .

調査する


Start here