Memulai
hello.sh
#!/bin/bash
VAR = "dunia"
echo "Halo $VAR!" # => Halo dunia!
Menjalankan skrip
$ bash hello.sh
Variabel-variabel
NAME = "John"
echo ${NAME} # => John (Variabel)
echo $NAME # => John (Variabel)
echo "$NAME" # => John (Variabel)
echo '$NAME' # => $NAME (String yang tepat)
echo "${NAMA}!" # => John! (Variabel)
NAME = "John" # => Kesalahan (tentang spasi)
Komentar
# Ini adalah komentar Bash sebaris.
: '
Ini adalah
komentar yang sangat rapi
di bash
'
Komentar multi-baris menggunakan :'
untuk membuka dan ``` untuk menutup
Argumen
| Ekspresi | Deskripsi | Deskripsi
|————-|—————————————|
| $1
… $9
| Parameter 1 … 9 |
| $1
| Argumen pertama |
| ${10}
| Parameter posisi 10 |
| $#
| Jumlah argumen | | $#
| Jumlah argumen
| $$
| Id proses dari shell |
| $*
| Semua argumen |
| $@
| Semua argumen, mulai dari yang pertama
| $-
| Pilihan saat ini | | $_
| Pilihan saat ini
| $_
| Argumen terakhir dari perintah sebelumnya | | $_
| Argumen terakhir dari perintah sebelumnya
Lihat: Parameter khusus
Fungsi
get_nama() {
echo "John"
}
echo "Anda adalah $(get_nama)"
Lihat: Fungsi
Kondisional
if [[ -z "$string" ]]; then
echo "String kosong"
elif [ [ -n "$string" ]]; then
echo "String tidak kosong"
fi
Lihat: Kondisional
Ekspansi penjepit
echo {A,B}.js
| Ekspresi | Deskripsi | Keterangan
|————|———————|
| {A,B}
| Sama seperti A B
| | Sama seperti A B |
{A,B}.js| Sama seperti
A.js B.js` | |A
Lihat: Perluasan penjepit
Eksekusi shell
# => Saya berada di /path/of/current
echo "Saya berada di $(PWD)"
# Sama seperti:
echo "Saya di `pwd`"
Lihat: Substitusi perintah
Ekspansi Parameter Bash
Sintaks
| Kode | Deskripsi | Keterangan
|——————-|———————|
| ${FOO%suffix}
| Hapus akhiran |
| ${FOO#awalan}
| Menghapus awalan |
| ${FOO%%suffix}
| Hapus akhiran panjang |
| ${FOO#awalan}
| Hapus awalan panjang |
| ${FOO/from/to}
| Ganti kecocokan pertama | | Ganti kecocokan pertama
| ${FOO//from/to}
| Ganti semua |
| ${FOO/%dari/ke}
| Ganti akhiran |
| ${FOO/#from/to}
| Ganti awalan |
Substring
Ekspresi | Deskripsi |
---|---|
${FOO:0:3} |
Substring (posisi, panjang) |
${FOO:(-3):3} |
Substring dari kanan |
Panjang
| Ekspresi | Deskripsi | Keterangan
|————|——————|
| ${#FOO}
| Panjang dari $FOO
|
Nilai default
Ekspresi | Deskripsi |
---|---|
${FOO:-val} |
$FOO , atau val jika tidak disetel |
${FOO:=val} |
Setel $FOO ke val jika tidak disetel |
${FOO:+val} |
val jika $FOO disetel |
${FOO:?message} |
Tampilkan pesan dan keluar jika $FOO tidak disetel |
Substitusi
echo ${makanan:-Kue} #=> $makanan atau "Kue"
STR = "/path/to/foo.cpp"
echo ${STR%.cpp} # /path/to/foo
echo ${STR%.cpp}.o # /path/to/foo.o
echo ${STR%/*} # /path/to
echo ${STR##*.} # cpp (ekstensi)
echo ${STR##*/} # foo.cpp (jalur dasar)
echo ${STR#*/} # path/to/foo.cpp
echo ${STR##*/} # foo.cpp
echo ${STR/foo/bar} # /path/to/bar.cpp
Mengiris
`` `bash name = “John” echo ${nama} # => John echo ${nama:0:2} # => Jo echo ${nama::2} # => Jo echo ${nama::-1} # => Joh echo ${nama:(-1)} # => n echo ${nama:(-2)} # => hn echo ${nama:(-2):2} # => hn
length = 2 echo ${nama:(0):panjang} # => Jo
Lihat: [Perluasan parameter](http://wiki.bash-hackers.org/syntax/pe)
### basepath & dirpath
```bash
SRC = "/path/to/foo.cpp"
BASEPATH=${SRC##*/}
echo $BASEPATH # => "foo.cpp"
DIRPATH=${SRC%$BASEPATH}
echo $DIRPATH # => "/path/to/"
Transform
STR = "HALO DUNIA!"
echo ${STR,} # => HELLO DUNIA!
echo ${STR,,} # => halo dunia!
STR = "halo dunia!"
echo ${STR^} # => halo dunia!
echo ${STR^^} # => HALO DUNIA!
ARR = (halo dunia)
echo "${ARR[@],}" # => halo dunia
echo "${ARR[@]^}" # => halo dunia
Larik Bash
Mendefinisikan larik
Buah-buahan = ('Apel' 'Pisang' 'Jeruk')
Buah-buahan [0] = "Apel"
Buah-buahan [1] = "Pisang"
Buah-buahan [2] = "Jeruk"
ARRAY1=(foo{1..2}) # => foo1 foo2
ARRAY2=({A..D}) # => A B C D
# Penggabungan => foo1 foo2 A B C D
ARRAY3=(${ARRAY1[@]} ${ARRAY2[@]})
# mendeklarasikan construct
mendeklarasikan -a Bilangan = (1 2 3)
Bilangan+=(4 5) # Menambahkan => 1 2 3 4 5
Pengindeksan
- | - |
---|---|
${Buah-buahan[0]} |
Elemen pertama |
${Buah-buahan[-1]} |
Elemen terakhir |
${Buah-buahan[*]} |
Semua elemen |
${Buah-buahan[@]} |
Semua elemen |
${#Buah-buahan[@]} |
Jumlah semua |
${#Buah-buahan} |
Panjang pertama |
${#Buah-buahan[3]} |
Panjang ke-n |
${Buah-buahan[@]:3:2} |
Rentang |
${!Buah-buahan[@]} |
Kunci dari semua |
Iterasi
Buah-buahan = ('Apel' 'Pisang' 'Jeruk')
for e in "${Buah-buahan[@]}"; do
echo $e
selesai
Dengan indeks
for i in "${!Buah-buahan[@]}"; do
printf "%s\t%s\n" "$i" "${Buah-buahan[$i]}"
selesai
Operasi
Buah-buahan=("${Buah-buahan[@]}" "Semangka") # Dorong
Buah-buahan+=('Semangka') # Juga Dorong
Buah-buahan=( ${Buah-buahan[@]/Ap*/} ) # Hapus dengan pencocokan regex
unset Buah-Buahan[2] # Hapus satu item
Buah-buahan=("${Buah-buahan[@]}") # Duplikat
Buah-buahan=("${Buah-buahan[@]}" "${Buah-buahan[@]}") # Menggabungkan
lines=(`cat "logfile"`) # Baca dari file
Larik sebagai argumen
fungsi extract()
{
local -n myarray = $ 1
local idx = $ 2
echo "${myarray[$idx]}"
}
Buah-buahan = ('Apel' 'Pisang' 'Jeruk')
ekstrak Buah-buahan 2 # => Jeruk
Kamus Bash
Mendefinisikan
mendeklarasikan -A suara
suara [anjing] = "gonggongan"
suara [sapi] = "melenguh"
suara [burung] = "kicau"
suara [serigala] = "lolongan"
Bekerja dengan kamus
gema ${bunyi[anjing]} # Suara anjing
echo ${suara[@]} # Semua nilai
echo ${!suara[@]} # Semua kunci
gema ${#bunyi[@]} # Jumlah elemen
unset suara[anjing] # Hapus anjing
Iterasi
for val in "${suara[@]}"; do
echo $val
selesai
for key in "${!sounds[@]}"; do
menggemakan $kunci
selesai
Kondisi Bash
Kondisi bilangan bulat
| Kondisi | Deskripsi | Keterangan
|———————|———————————————|
| [[ NUM -eq NUM ]]
| Eq sama dengan |
| [[ NUM -ne NUM ]]
| Not esama |
| [[ NUM -lt NUM ]]
| Less than |
| [[ NUM -le NUM ]]
| L lebih kecil dari atau esama |
| [[ NUM -gt NUM ]]
| G lebih dari than |
| [[ NUM -ge NUM ]]
| G lebih besar dari atau esama |
| (( NUM < NUM )
| Kurang dari |
| (( NUM <= NUM ))
| Kurang dari atau sama dengan |
| (( NUM > NUM )
| Lebih besar dari |
| (( NUM >= NUM )
| Lebih besar dari atau sama dengan |
Kondisi string
Kondisi | Deskripsi |
---|---|
[[ -z STR ]] |
String kosong |
[[[ -n STR ]] |
N bukan string kosong |
[[ STR == STR ]] |
Sama dengan |
[[ STR = STR ]] |
Sama (Sama di atas) |
[[ STR < STR ]] |
Kurang dari (ASCII) |
[[ STR > STR ]] |
Lebih besar dari (ASCII) |
[[ STR != STR ]] |
Tidak Sama |
[[ STR =~ STR ]] |
Regexp |
Contoh
String
if [[ -z "$string" ]]; then
echo "String kosong"
elif [ [ -n "$string" ]]; then
echo "String tidak kosong"
else
echo "Ini tidak pernah terjadi"
fi
Kombinasi
if [[ X && Y ]]; then
...
fi
Sama dengan
if [[ "$A" == "$B" ]]; then
...
fi
Regex
if [[ '1. abc' =~ ([a-z]+) ]]; then
echo ${BASH_REMATCH[1]}
fi
Lebih kecil
if (( $a < $b )); then
echo "$a lebih kecil dari $b"
fi
Ada
if [[ -e "file.txt" ]]; then
echo "file ada"
fi
Kondisi file
| Kondisi | Deskripsi | Keterangan
|——————-|—————————————-|
| [[ -e FILE ]]
| E ada |
| [[ -d FILE ]]
| Ddirektori |
| [[[ -f FILE ]]
| File |
| [[[ -h FILE ]]
| Symlink |
| [[[ -s FILE ]]
| Ukuran > 0 byte |
| [[[ -r FILE ]]
| Rdapat dibaca |
| [[[ -w FILE ]]
| Wdapat dibaca |
| [[[ -x FILE ]]
| Dapat dieksekusi |
| [[ f1 -nt f2 ]]
| f1 newer than f2 |
| [[ f1 -ot f2 ]]
| f2 older than f1 |
| [[ f1 -ef f2 ]]
| File yang sama
Kondisi lainnya
| Kondisi | Deskripsi | Keterangan
|———————-|———————-|
| [[ -o noclobber ]]
| Jika OPTION diaktifkan |
| [[ ! EXPR ]]
| Tidak |
| [[ X && Y ]]
| Dan |
| [[ X || Y ]]
| Atau |
logika dan, atau
if [ "$1" = 'y' -a $2 -gt 0 ]; then
echo "ya"
fi
if [ "$1" = 'n' -o $2 -lt 0 ]; then
echo "tidak"
fi
Bash Loops
Perulangan dasar untuk perulangan
for i in /etc/rc.*; do
echo $i
selesai
Perulangan seperti C untuk perulangan
for ((i = 0 ; i < 100 ; i++)); do
echo $i
selesai
Rentang
for i in {1..5}; do
echo "Selamat datang $i"
selesai
Dengan ukuran langkah
for i in {5..50..5}; do
echo "Selamat datang $i"
selesai
Kenaikan otomatis
i=1
while [[ $i -lt 4 ]]; do
echo "Nomor: $i"
((i++))
selesai
Pengurangan otomatis
i=3
while [[ $i -gt 0 ]]; do
echo "Nomor: $i"
((i--))
selesai
Lanjutkan
for number in $(seq 1 3); do
if [ [ $nomor == 2 ]]; then
continue
fi
echo "$jumlah"
selesai
Istirahat
for number in $(seq 1 3); do
if [[ $number == 2 ]]; then
# Lewati seluruh sisa perulangan.
istirahat;
fi
# Ini hanya akan mencetak 1
echo "$number"
selesai
Sampai
count = 0
until [ $count -gt 10 ]; do
echo "$hitung"
((count++))
selesai
Selamanya
while true; do
# Berikut adalah beberapa kode.
done
Selamanya (singkatan)
while :; do
# berikut adalah beberapa kode.
done
Membaca baris
cat file.txt | while baca baris; do
echo $baris
selesai
Fungsi Bash
Mendefinisikan fungsi
myfunc() {
echo "halo $1"
}
# Sama seperti di atas (sintaks alternatif)
function myfunc() {
echo "halo $1"
}
myfunc "John"
Mengembalikan nilai
myfunc() {
local myresult = 'suatu nilai'
echo $myresult
}
result = "$(myfunc)"
Menimbulkan kesalahan
myfunc() {
return 1
}
if myfunc; then
echo "sukses"
else
echo "kegagalan"
fi
Opsi Bash
Opsi ###
# Menghindari file overlay
# (echo "hi" > foo)
set -o noclobber
# Digunakan untuk keluar saat terjadi kesalahan
# Menghindari kesalahan yang bertingkat-tingkat
set -o errexit
# Menyingkap kegagalan yang tersembunyi
set -o pipefail
# Mengekspos variabel yang tidak diset
set -o nounset
Opsi glob
# Glob yang tidak cocok akan dihapus
# ('*.foo' => '')
shopt -s nullglob
# Kesalahan lemparan glob yang tidak cocok
shopt -s failglob
# Globs yang tidak peka huruf besar/kecil
shopt -s nocaseglob
# Karakter pengganti cocok dengan dotfile
# ("*.sh" => ".foo.sh")
shopt -s dotglob
# Izinkan ** untuk pencocokan rekursif
# ('lib/**/*.rb' => 'lib/a/b/c.rb')
shopt -s globstar
Riwayat Bash
Perintah
Perintah | Deskripsi |
---|---|
history |
Menampilkan riwayat |
sudo !! |
Menjalankan perintah sebelumnya dengan sudo |
shopt -s histverify |
Jangan langsung mengeksekusi hasil yang diperluas |
Ekspansi
| Ekspresi | Deskripsi | Keterangan |————–|——————————————————|
| !-n
| Perluas perintah terbaru ke-n | | n
| !n
| Perluas perintah ke-n dalam riwayat | | !n
| Perluas perintah ke-n dalam riwayat
| !<perintah>
| Memperluas pemanggilan terbaru dari perintah <perintah>
| | Memperluas
Operasi
Kode | Deskripsi |
---|
| !!:s/<FROM>/<TO>/
| Mengganti kemunculan pertama dari <FROM>
menjadi <TO>
dalam perintah terakhir | | !!:s/<FROM>/<TO>/
| Mengganti kemunculan pertama dari <FROM>
menjadi <TO>
dalam perintah terakhir
| !!!:gs/<FROM>/<TO>/
| Ganti semua kemunculan <FROM>
menjadi <TO>
dalam perintah terbaru | | Ganti semua kemunculan <FROM>
menjadi <TO>
dalam perintah terbaru | | Ganti semua kemunculan <FROM>
menjadi <TO>
dalam perintah terbaru
| !$:h
| Perluas hanya direktori dari parameter terakhir dari perintah terbaru | | !$:h
| Perluas hanya direktori dari parameter terakhir dari perintah terbaru
!!
dan !$
dapat diganti dengan ekspansi yang valid.
Irisan
| Kode | Deskripsi | Keterangan |———-|——————————————————————————————|
| !!:n-m
| Perluas rentang token dari perintah terbaru | | !$
| Perluas rentang token dari perintah terbaru
| !!:n-$
| Memperluas token ke-n hingga terakhir dari perintah terbaru | | !$
| Memperluas token ke-n hingga terakhir dari perintah terbaru
!!
dapat diganti dengan ekspansi yang valid, misalnya !cat
, !-2
, !42
, dll.
Lain-lain
Perhitungan numerik
$((a + 200)) # Tambahkan 200 ke $a
$(($RANDOM%200)) # Angka acak 0..199
Subshells
(cd somedir; echo "Saya sekarang berada di $PWD")
pwd # masih di direktori pertama
Memeriksa perintah-perintah
perintah -V cd
#=> "cd adalah sebuah fungsi/alias/apa pun"
Pengalihan
python hello.py > output.txt # stdout ke (file)
python hello.py >> output.txt # stdout to (file), append
python hello.py 2> error.log # stderr ke (file)
python hello.py 2>&1 # stderr ke stdout
python hello.py 2>/dev/null # stderr ke (null)
python hello.py &>/dev/null # stdout dan stderr ke (null)
python hello.py < foo.txt # mengumpankan foo.txt ke stdin untuk python
Sumber relatif
sumber "${0%/*}/../share/foo.sh"
Direktori skrip
DIR = "${0%/*}"
Huruf besar/kecil
huruf besar "$ 1" di
mulai | naik)
gelandangan naik
;;
*)
echo "Penggunaan: $ 0 {start|stop|ssh}"
;;
esac
Kesalahan perangkap
trap 'echo Kesalahan di sekitar $LINENO' ERR
atau
traperr() {
echo "KESALAHAN: ${BASH_SOURCE[1]} di sekitar ${BASH_LINENO[0]}"
}
set -o errtrace
trap traperr ERR
printf
printf "Halo %s, saya %s" Sven Olga
#=> "Halo Sven, saya Olga
printf "1 + 1 = %d" 2
#=> "1 + 1 = 2"
printf "Cetak sebuah float: %f" 2
#=> "Cetak sebuah float: 2.000000"
Mendapatkan opsi
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
-V | --versi )
echo $ versi
keluar
;;
-s | --string )
shift; string = $ 1
;;
-f | --flag )
flag = 1
;;
esac; shift; done
if [ [ "$1" == '--' ]]; then shift; fi
Periksa hasil perintah
if ping -c 1 google.com; then
echo "Tampaknya Anda memiliki koneksi internet yang berfungsi"
fi
Variabel khusus
| Ekspresi | Deskripsi | Keterangan
|————|——————————|
| $?
| Status keluar dari tugas terakhir |
| $!
| PID tugas latar belakang terakhir |
| $$
| PID dari shell |
| $0
| Nama file dari skrip shell |
Lihat [Parameter khusus] (http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables).
Grep cek
if grep -q 'foo' ~/.bash_history; then
echo "Anda sepertinya pernah mengetik 'foo' di masa lalu"
fi
Backslash lolos dari
- !
- "
- #
- &
- '
- (
- )
- ,
- ;
- <
- >
- [
- |
- \
- ]
- ^
- {
- }
- `
- $
- *
- ? {.cols-4 .marker-none}
Melarikan diri dari karakter khusus ini dengan \
Heredoc
kucing <<END
halo dunia
END
Pergi ke direktori sebelumnya
pwd # /home/user/foo
cd bar/
pwd # /home/user/foo/bar
cd -
pwd # /home/user/foo
Membaca masukan
echo -n "Lanjutkan? [y/n]: "
baca ans
echo $ans
read -n 1 ans # Hanya satu karakter
Eksekusi bersyarat
git commit && git push
git commit || echo "Komit gagal"
Mode ketat
set -euo pipefail
IFS = $'\n\t'
Lihat: Mode ketat bash tidak resmi
Argumen opsional
args=("$@")
args+=(foo)
args+=(bar)
echo "${args[@]}"
Menempatkan argumen ke dalam larik dan kemudian menambahkan
Lihat juga
- Devhints (devhints.io)
- Bash-hackers wiki (bash-hackers.org)
- Shell vars (bash-hackers.org)
- Belajar bash dalam beberapa menit (learnxinyminutes.com)
- Panduan Bash (mywiki.wooledge.org)
- ShellCheck (shellcheck.net)
- shell - Standard Shell (devmanual.gentoo.org)