Gabay

Bash script para sa baguhan: unang script, variable, kondisyon, loop, at cron

Na-update: · Skillaria.Top

Ang bash script ay plain text na file na may mga utos ng shell, nagsisimula sa linyang #!/bin/bash, binibigyan ng permission sa pagpapatakbo gamit ang chmod +x, at pinapatakbo gamit ang ./script.sh. Gumagamit ang script ng variable, mga argumentong $1 at $2, kondisyong if, loop na for at while; ang pag-uulit ayon sa iskedyul ay itinatakda gamit ang crontab -e.

Ang bash script ay karaniwang text file na naglalaman ng mga utos na kung hindi ay tatype mo nang isa-isa sa terminal. Nagsisimula ang script sa shebang na linyang #!/bin/bash, binibigyan ng permission na tumakbo gamit ang chmod +x, at pinapatakbo gamit ang ./script.sh. Mula unang linya hanggang pagpapatakbo ayon sa iskedyul ang gabay na ito sa bash script para sa baguhan: variable, argumento, kondisyon, loop, error handling, at cron.

Ang unang bash script sa loob ng isang minuto

Gumawa ng file gamit ang anumang text editor, halimbawa nano:

nano hello.sh
#!/bin/bash
# Unang script: pagbati at kaunting impormasyon tungkol sa sistema
echo "Kumusta, $USER!"
echo "Ngayon: $(date +%Y-%m-%d)"
echo "Nasa: $(pwd)"

I-save (Ctrl+O, Enter, Ctrl+X), bigyan ng permission na tumakbo, at patakbuhin:

$ chmod +x hello.sh
$ ./hello.sh
Kumusta, alice!
Ngayon: 2026-10-12
Nasa: /home/alice

Ang mga linyang nagsisimula sa # ay komento. Inilalagay ng $(utos) ang output ng utos nang direkta sa loob ng teksto.

Shebang: bakit kailangan ang unang linya

Sinasabi ng linyang #!/bin/bash sa sistema kung aling interpreter ang gagamitin sa file. Kung wala ito, papatakbuhin ang script ng anumang shell na available, at sa ilang sistema ang /bin/sh ay hindi bash kundi dash na mas simple, kung saan ang ilang construct ay hindi gagana.

Karaniwan din ang #!/usr/bin/env bash: hinahanap nito ang bash sa PATH, kapaki-pakinabang kapag wala ang bash sa /bin.

Paano patakbuhin ang script at bakit may ./

Dalawa ang paraan:

  • ./hello.sh — kailangan ang shebang at ang permission na x. Kailangan ang prefix na ./ dahil wala sa PATH ang kasalukuyang direktoryo.
  • bash hello.sh — hindi kailangan ang permission sa pagpapatakbo, dahil tahasang tinukoy ang interpreter.

Kung walang ./, makikita mo ang command not found, at kung walang chmod +x, makikita mo ang Permission denied — ito ang dalawang dahilang iyon. Para matawag ang sarili mong script sa pangalan mula saanman, ilagay ito sa ~/bin o /usr/local/bin.

Mga variable

Itinatakda ang variable nang walang espasyo sa magkabilang gilid ng =, at binabasa gamit ang $:

#!/bin/bash
name="backup"
dir="/var/backups"
today=$(date +%F)

echo "File: ${dir}/${name}-${today}.tar.gz"

Inihihiwalay ng curly braces ang pangalan ng variable sa nakapalibot na teksto. Mali ang linyang name = "backup" na may espasyo: susubukan ng bash na patakbuhin ang utos na name.

Mahalaga ang mga quote

Sa double quotes, pinapalitan ang mga variable; sa single quotes, hindi. Lagi mong ilagay ang mga variable sa double quotes, kung hindi ay mahahati sa dalawang argumento ang pangalan ng file na may espasyo.

file="ulat ko.txt"
rm $file      # mali: susubukang burahin ang "ulat" at "ko.txt"
rm "$file"    # tama
echo '$HOME'  # ipapakita nang literal ang $HOME
echo "$HOME"  # ipapakita ang /home/alice

Mga environment variable

Itinatakda ng sistema ang mga variable tulad ng $HOME, $USER, $PATH. Maipapasa ang sarili mong variable sa mga child process gamit ang export. Ang permanenteng settings ay inilalagay sa ~/.bashrc o ~/.profile.

Mga argumento ng script

Ang mga value na ibinigay sa pagpapatakbo ay nasa $1, $2, at iba pa.

VariableLaman
$0pangalan ng script
$1, $2…una, pangalawang argumento
$#bilang ng argumento
"$@"lahat ng argumento nang hiwa-hiwalay
$?exit code ng huling utos
$$PID ng kasalukuyang script
#!/bin/bash
echo "Ang script na $0 ay may $# argumento"
echo "Una: $1"
$ ./args.sh nginx 80
Ang script na ./args.sh ay may 2 argumento
Una: nginx

Kinukuha ang input mula sa user gamit ang read: read -p "Ilagay ang pangalan: " name.

Kondisyong if

Bawat utos ay nagbabalik ng exit code: 0 ay tagumpay, anumang iba ay error. Sinusuri ng if ang code na ito mismo. Para sa paghahambing, gamitin ang [[ ... ]], at kailangan ang mga espasyo sa loob ng mga bracket.

#!/bin/bash
if [[ $# -eq 0 ]]; then
    echo "Gamit: $0 <direktoryo>"
    exit 1
fi

if [[ -d "$1" ]]; then
    echo "Umiiral ang direktoryong $1"
elif [[ -f "$1" ]]; then
    echo "$1 ay file, hindi direktoryo"
else
    echo "Hindi nahanap ang $1"
fi
PagsusuriKahulugan
-f fileumiiral ang regular na file
-d dirumiiral ang direktoryo
-e pathumiiral ang path
-x filemaaaring patakbuhin ang file
-z "$var" / -n "$var"walang laman / may laman ang string
"$a" == "$b", !=paghahambing ng string
-eq -ne -lt -le -gt -gepaghahambing ng numero

Maaari ring suriin nang direkta ang anumang utos:

if systemctl is-active --quiet nginx; then
    echo "tumatakbo ang nginx"
else
    echo "huminto ang nginx"
fi

Para sa maraming pagpipilian, mas maayos ang case:

case "$1" in
    start)   echo "Sinisimulan" ;;
    stop)    echo "Hinihinto" ;;
    *)       echo "Hindi kilalang utos: $1"; exit 1 ;;
esac

Mga loop na for at while

for: dumaan sa listahan

for host in web1 web2 db1; do
    echo "Sinusuri ang $host"
    ping -c 1 -W 1 "$host" > /dev/null && echo "  maaabot" || echo "  hindi maabot"
done

for file in /var/log/*.log; do
    echo "$file: $(wc -l < "$file") linya"
done

for i in {1..5}; do
    echo "Subok $i"
done

while: habang totoo ang kondisyon

Klasikong halimbawa ang pagbasa ng file linya-linya:

while read -r user; do
    echo "User: $user"
done < users.txt

At ang paghihintay na maging handa ang serbisyo:

count=0
until curl -sf http://localhost:8080/health > /dev/null; do
    count=$((count + 1))
    if [[ $count -ge 10 ]]; then
        echo "Hindi nagsimula ang serbisyo"
        exit 1
    fi
    sleep 3
done
echo "Handa na ang serbisyo"

Isinusulat ang aritmetika sa bash sa double parentheses: $((a + b)). Buong numero lamang ang kaya nito.

Mga function

Inilalagay sa function ang paulit-ulit na code. Ang mga argumento sa loob ng function ay $1, $2 pa rin, at pinipigilan ng local ang variable na lumabas.

log() {
    local level="$1"; shift
    echo "$(date '+%F %T') [$level] $*"
}

log INFO "Sinisimulan ang backup"
log ERROR "Kulang ang espasyo sa disk"

Error handling: set -euo pipefail

Bilang default, nagpapatuloy ang bash pagkatapos mabigo ang isang utos — at maaaring "magtagumpay" ang backup script nang hindi kumokopya ng kahit ano. Karaniwang inilalagay ang strict mode sa simula ng script:

#!/bin/bash
set -euo pipefail
  • -e — huminto sa unang error.
  • -u — ituring na error ang paggamit ng variable na hindi pa nadeklara (pinoprotektahan laban sa rm -rf "$DIR/" kapag walang laman ang DIR).
  • -o pipefail — ituring na bigo ang pipeline kapag bumigo ang alinmang bahagi nito.

Para sa debugging, patakbuhin ang script bilang bash -x script.sh: ipi-print ng bash ang bawat utos bago ito patakbuhin. Para makahanap ng karaniwang pagkakamali bago patakbuhin, makakatulong ang shellcheck.

Praktikal na halimbawa: backup script

#!/bin/bash
set -euo pipefail

SRC="${1:-/var/www}"
DST="/var/backups/site"
KEEP_DAYS=7
STAMP=$(date +%F_%H-%M)

mkdir -p "$DST"
tar -czf "$DST/site-$STAMP.tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"
echo "Nagawa ang archive na $DST/site-$STAMP.tar.gz"

# burahin ang mga archive na mas luma sa KEEP_DAYS na araw
find "$DST" -name "site-*.tar.gz" -mtime +"$KEEP_DAYS" -delete

Ang ibig sabihin ng ${1:-/var/www} ay "ang unang argumento, at kung wala ay /var/www". I-save ang script bilang /usr/local/bin/backup-site.sh at bigyan ng permission sa pagpapatakbo: sudo chmod +x /usr/local/bin/backup-site.sh.

Pagpapatakbo ayon sa iskedyul: cron

Ang cron ay serbisyong nagpapatakbo ng mga utos ayon sa iskedyul. Ine-edit ang mga job ng user gamit ang crontab -e, tinitingnan gamit ang crontab -l, at ang mga job ng root ay gamit ang sudo crontab -e.

Binubuo ang linya ng job ng limang field ng oras at ng utos:

# minuto oras araw_ng_buwan buwan araw_ng_linggo utos
30 2 * * * /usr/local/bin/backup-site.sh >> /var/log/backup.log 2>&1
IskedyulKailan tatakbo
*/5 * * * *bawat 5 minuto
0 * * * *sa simula ng bawat oras
30 2 * * *araw-araw sa 02:30
0 9 * * 1-5tuwing weekdays sa 09:00
0 3 1 * *sa 03:00 ng unang araw ng bawat buwan
@rebootminsan pagkatapos mag-boot

Bakit gumagana ang script kapag manual, pero hindi sa cron

  • Iba ang environment. Pinapatakbo ng cron ang mga job na may minimal na PATH at hindi binabasa ang ~/.bashrc. Isulat ang buong path ng mga utos at file, o itakda ang PATH sa simula ng crontab.
  • Iba ang kasalukuyang direktoryo. Nagsisimula ang job sa home directory, hindi kung nasaan ang script. Gumamit ng absolute path.
  • Ang simbolong %. Sa crontab, ang % ay nangangahulugang bagong linya, kaya kailangang i-escape bilang \% ang date +%F na nakasulat nang diretso sa job. Mas madaling ilagay ang utos sa script.
  • Nawawala ang output. I-redirect ang output sa log (>> file 2>&1), kung hindi ay hindi mo makikita ang error. Makikita ang mga pagpapatakbo ng cron gamit ang journalctl -u cron (sa mga sistemang RHEL, crond ang pangalan ng serbisyo).

Sa mga sistemang may systemd, maaaring gamitin ang systemd timer bilang alternatibo sa cron: isinusulat nito ang output sa journal at kayang habulin ang mga pagpapatakbong nalampasan.

Buod

Ang bash script para sa baguhan ay file na may shebang na #!/bin/bash, permission na tumakbo, at pagkakasunod-sunod ng mga utos. Ilagay ang mga variable sa quotes, suriin ang mga argumento gamit ang if, gamitin ang for at while loop, at ang strict mode na set -euo pipefail — at makakakuha ka ng maaasahang kasangkapan sa automation na kayang patakbuhin ng cron ayon sa iskedyul. Ang bash script, environment, at cron ay itinuturo nang praktikal sa kursong Linux.

Mga madalas itanong

Ano ang pagkakaiba ng bash at sh?

Ang sh ay ang pamantayang POSIX shell, habang ang bash ay pinalawak na bersyon na may array, double parentheses, at iba pang kaginhawahan. Ang script na gumagamit ng bash constructs ay dapat patakbuhin gamit ang bash, hindi sh.

Anong extension dapat ang bash script?

Hindi binibigyang-pansin ng Linux ang extension; tinutukoy ng shebang ang interpreter. Ang .sh ay kombensiyon lamang para malaman ng tao na script ito.

Paano ligtas na ipapasa ang password sa script?

Huwag ipasa bilang argumento, dahil nakikita ito ng ibang user sa ps. Gumamit ng environment variable na galing sa file na may permission 600, o read -s para mag-input nang hindi nakikita ang tina-type.

Paano malalaman kung root ang nagpapatakbo ng script?

Ikumpara ang user ID sa zero: if [[ $EUID -ne 0 ]]; then echo "Kailangan ng root"; exit 1; fi.

Paano patakbuhin ang script sa background para hindi huminto kapag nag-log out sa SSH?

Gamitin ang nohup ./script.sh &, isang tmux o screen session; at para sa tuloy-tuloy na pagpapatakbo, gawing systemd service ang script.

Pag-aralan ito sa video

Detalyadong tinatalakay ang paksang ito, may praktis, sa kursong “Linux: с нуля до уверенного администрирования”.

Pumunta sa kurso