शुरुआती के लिए Bash स्क्रिप्ट: पहली स्क्रिप्ट, वेरिएबल, शर्तें, लूप और cron
Bash स्क्रिप्ट कमांड वाली सादी टेक्स्ट फ़ाइल है, जो लाइन #!/bin/bash से शुरू होती है, chmod +x से चलाने का अधिकार पाती है और ./script.sh के रूप में चलती है। स्क्रिप्ट में वेरिएबल, आर्गुमेंट $1 और $2, if शर्तें, for व while लूप इस्तेमाल होते हैं, और नियमित शेड्यूल crontab -e से सेट होता है।
Bash स्क्रिप्ट एक साधारण टेक्स्ट फ़ाइल है जिसमें वे कमांड हैं जिन्हें आप वरना टर्मिनल में एक-एक करके टाइप करते। स्क्रिप्ट की शुरुआत shebang लाइन #!/bin/bash से होती है, उसे chmod +x से चलाने का अधिकार मिलता है और उसे ./script.sh के रूप में चलाया जाता है। यह मार्गदर्शिका शुरुआती के लिए bash स्क्रिप्ट की पहली लाइन से लेकर शेड्यूल पर चलने तक है: वेरिएबल, आर्गुमेंट, शर्तें, लूप, त्रुटि संभालना और cron।
पहली bash स्क्रिप्ट एक मिनट में
किसी भी एडिटर में फ़ाइल बनाएँ, जैसे nano में:
nano hello.sh
#!/bin/bash
# पहली स्क्रिप्ट: स्वागत और सिस्टम की थोड़ी जानकारी
echo "नमस्ते, $USER!"
echo "आज: $(date +%Y-%m-%d)"
echo "आप यहाँ हैं: $(pwd)"
सेव करें (Ctrl+O, Enter, Ctrl+X), चलाने का अधिकार दें और चलाएँ:
$ chmod +x hello.sh
$ ./hello.sh
नमस्ते, alice!
आज: 2026-10-12
आप यहाँ हैं: /home/alice
# से शुरू होने वाली लाइनें टिप्पणी (comment) हैं। $(कमांड) कमांड का आउटपुट सीधे लाइन में डाल देता है।
Shebang: पहली लाइन क्यों ज़रूरी है
लाइन #!/bin/bash सिस्टम को बताती है कि फ़ाइल किस इंटरप्रेटर से चलानी है। इसके बिना स्क्रिप्ट जो शेल हाथ लगे उसी से चलेगी, और कुछ सिस्टम में /bin/sh bash नहीं बल्कि सादा dash होता है, जहाँ कुछ निर्माण काम नहीं करते।
अक्सर #!/usr/bin/env bash भी लिखा जाता है: यह PATH में bash ढूँढता है, जो तब सुविधाजनक है जब bash /bin में न हो।
स्क्रिप्ट कैसे चलाएँ और ./ क्यों
दो तरीक़े हैं:
./hello.sh— shebang औरxअधिकार चाहिए।./उपसर्ग ज़रूरी है, क्योंकि मौजूदा डायरेक्टरी PATH में नहीं होती।bash hello.sh— चलाने का अधिकार नहीं चाहिए, इंटरप्रेटर साफ़ लिखा है।
अगर ./ के बिना command not found दिखे, और chmod +x के बिना Permission denied, तो ये ठीक वही दो कारण हैं। अपनी स्क्रिप्ट को कहीं से भी नाम से चलाने के लिए उसे ~/bin या /usr/local/bin में रखें।
वेरिएबल
वेरिएबल = के आसपास बिना स्पेस के लिखा जाता है, और उसे $ से पढ़ा जाता है:
#!/bin/bash
name="backup"
dir="/var/backups"
today=$(date +%F)
echo "फ़ाइल: ${dir}/${name}-${today}.tar.gz"
घुंघराले कोष्ठक ({}) वेरिएबल का नाम आसपास के टेक्स्ट से अलग करते हैं। लाइन name = "backup" स्पेस के साथ ग़लत है: bash name नाम की कमांड चलाने की कोशिश करेगा।
उद्धरण चिह्न मायने रखते हैं
डबल कोट में वेरिएबल की जगह मान आता है, सिंगल कोट में नहीं। वेरिएबल लगभग हमेशा डबल कोट में लें, वरना स्पेस वाला फ़ाइल नाम दो आर्गुमेंट में बँट जाएगा।
file="मेरी रिपोर्ट.txt"
rm $file # ग़लत: «मेरी» और «रिपोर्ट.txt» हटाने की कोशिश करेगा
rm "$file" # सही
echo '$HOME' # शब्दशः $HOME छापेगा
echo "$HOME" # छापेगा /home/alice
एनवायरनमेंट वेरिएबल
$HOME, $USER, $PATH जैसे वेरिएबल सिस्टम सेट करता है। अपना वेरिएबल export से चाइल्ड प्रोसेस को दिया जा सकता है। स्थायी सेटिंग ~/.bashrc या ~/.profile में रखी जाती है।
स्क्रिप्ट के आर्गुमेंट
चलाते समय दिए गए मान $1, $2 आदि में मिलते हैं।
| ead> | |
|---|---|
| वेरिएबल | क्या रखता है |
$0 | स्क्रिप्ट का नाम |
$1, $2… | पहला, दूसरा आर्गुमेंट |
$# | आर्गुमेंट की संख्या |
"$@" | सभी आर्गुमेंट अलग-अलग |
$? | आख़िरी कमांड का एग्ज़िट कोड |
$$ | मौजूदा स्क्रिप्ट का PID |
#!/bin/bash
echo "स्क्रिप्ट $0 को $# आर्गुमेंट मिले"
echo "पहला: $1"
$ ./args.sh nginx 80
स्क्रिप्ट ./args.sh को 2 आर्गुमेंट मिले
पहला: nginx
उपयोगकर्ता से इनपुट read कमांड से लिया जाता है: read -p "नाम लिखें: " name।
if शर्तें
हर कमांड एक एग्ज़िट कोड लौटाती है: 0 मतलब सफलता, बाक़ी सब त्रुटि। if ठीक इसी कोड को जाँचता है। तुलना के लिए [[ ... ]] इस्तेमाल होता है, और कोष्ठकों के अंदर स्पेस ज़रूरी हैं।
#!/bin/bash
if [[ $# -eq 0 ]]; then
echo "उपयोग: $0 <डायरेक्टरी>"
exit 1
fi
if [[ -d "$1" ]]; then
echo "डायरेक्टरी $1 मौजूद है"
elif [[ -f "$1" ]]; then
echo "$1 एक फ़ाइल है, डायरेक्टरी नहीं"
else
echo "$1 नहीं मिला"
fi
| ead> | |
|---|---|
| जाँच | मतलब |
-f file | साधारण फ़ाइल मौजूद है |
-d dir | डायरेक्टरी मौजूद है |
-e path | पाथ मौजूद है |
-x file | फ़ाइल चलाई जा सकती है |
-z "$var" / -n "$var" | स्ट्रिंग ख़ाली है / ख़ाली नहीं |
"$a" == "$b", != | स्ट्रिंग की तुलना |
-eq -ne -lt -le -gt -ge | संख्याओं की तुलना |
कोई भी कमांड सीधे शर्त के रूप में जाँची जा सकती है:
if systemctl is-active --quiet nginx; then
echo "nginx चल रहा है"
else
echo "nginx बंद है"
fi
कई विकल्पों के लिए case सुविधाजनक है:
case "$1" in
start) echo "शुरू हो रहा है" ;;
stop) echo "बंद हो रहा है" ;;
*) echo "अज्ञात कमांड: $1"; exit 1 ;;
esac
for और while लूप
for: सूची पर घुमाना
for host in web1 web2 db1; do
echo "जाँच हो रही है $host"
ping -c 1 -W 1 "$host" > /dev/null && echo " उपलब्ध है" || echo " उपलब्ध नहीं है"
done
for file in /var/log/*.log; do
echo "$file: $(wc -l < "$file") लाइनें"
done
for i in {1..5}; do
echo "प्रयास $i"
done
while: जब तक शर्त सही है
फ़ाइल को लाइन-दर-लाइन पढ़ने का क्लासिक उदाहरण:
while read -r user; do
echo "यूज़र: $user"
done < users.txt
और सर्विस के चालू होने तक इंतज़ार:
count=0
until curl -sf http://localhost:8080/health > /dev/null; do
count=$((count + 1))
if [[ $count -ge 10 ]]; then
echo "सर्विस चालू नहीं हुई"
exit 1
fi
sleep 3
done
echo "सर्विस तैयार है"
bash में गणित डबल कोष्ठक में लिखा जाता है: $((a + b))। यह केवल पूर्णांकों के साथ काम करता है।
फ़ंक्शन
दोहराए जाने वाले कोड को फ़ंक्शन में डाला जाता है। फ़ंक्शन के अंदर आर्गुमेंट वही $1, $2 होते हैं, और local वेरिएबल को बाहर नहीं जाने देता।
log() {
local level="$1"; shift
echo "$(date '+%F %T') [$level] $*"
}
log INFO "बैकअप शुरू कर रहा हूँ"
log ERROR "डिस्क में जगह नहीं है"
त्रुटियाँ संभालना: set -euo pipefail
डिफ़ॉल्ट रूप से bash किसी विफल कमांड के बाद भी चलता रहता है, और बैकअप स्क्रिप्ट बिना कुछ कॉपी किए «सफलतापूर्वक» ख़त्म हो सकती है। इसलिए स्क्रिप्ट की शुरुआत में सख़्त मोड लिखा जाता है:
#!/bin/bash
set -euo pipefail
-e— पहली त्रुटि पर रुकना।-u— बिना घोषित वेरिएबल के इस्तेमाल को त्रुटि मानना (यहrm -rf "$DIR/"से बचाता है, जबDIRख़ाली हो)।-o pipefail— पाइप तब विफल माना जाए, जब उसका कोई भी हिस्सा विफल हो।
डीबग करने के लिए स्क्रिप्ट को bash -x script.sh से चलाएँ: bash हर कमांड चलाने से पहले उसे छापेगा। चलाने से पहले आम गलतियाँ shellcheck टूल से पकड़ी जा सकती हैं।
व्यावहारिक उदाहरण: बैकअप स्क्रिप्ट
#!/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 "आर्काइव बना: $DST/site-$STAMP.tar.gz"
# KEEP_DAYS दिनों से पुराने आर्काइव हटाएँ
find "$DST" -name "site-*.tar.gz" -mtime +"$KEEP_DAYS" -delete
लिखावट ${1:-/var/www} का अर्थ है: «पहला आर्गुमेंट; और अगर वह नहीं है, तो /var/www»। स्क्रिप्ट को /usr/local/bin/backup-site.sh के नाम से सेव करें और चलाने योग्य बनाएँ: sudo chmod +x /usr/local/bin/backup-site.sh।
शेड्यूल पर चलाना: cron
Cron वह सर्विस है जो कमांड शेड्यूल पर चलाती है। यूज़र के जॉब crontab -e से बदले जाते हैं, crontab -l से देखे जाते हैं, और root के जॉब sudo crontab -e से।
cron लाइन में पाँच समय-फ़ील्ड होते हैं, फिर कमांड:
# मिनट घंटा दिन_महीना महीना दिन_सप्ताह कमांड
30 2 * * * /usr/local/bin/backup-site.sh >> /var/log/backup.log 2>&1
| ead> | |
|---|---|
| शेड्यूल | कब चलता है |
*/5 * * * * | हर 5 मिनट में |
0 * * * * | हर घंटे की शुरुआत में |
30 2 * * * | हर दिन 02:30 पर |
0 9 * * 1-5 | सोमवार से शुक्रवार 09:00 पर |
0 3 1 * * | हर महीने की 1 तारीख़ को 03:00 पर |
@reboot | बूट के बाद एक बार |
स्क्रिप्ट हाथ से चलती है, cron में क्यों नहीं
- अलग वातावरण। Cron जॉब को न्यूनतम
PATHऔर आपकी~/.bashrcके बिना चलाता है। कमांड और फ़ाइलों के पूरे पाथ लिखें, या crontab की शुरुआत मेंPATHसेट करें। - अलग मौजूदा डायरेक्टरी। जॉब होम डायरेक्टरी से शुरू होता है, स्क्रिप्ट वाली डायरेक्टरी से नहीं। एब्सोल्यूट पाथ इस्तेमाल करें।
- % चिह्न। crontab में
%का मतलब नई लाइन होता है, इसलिए जॉब की लाइन मेंdate +%Fको\%से एस्केप करना होगा। आसान तरीक़ा यह है कि कमांड स्क्रिप्ट में डाल दें। - आउटपुट खो जाता है। आउटपुट लॉग में रीडायरेक्ट करें (
>> file 2>&1), वरना त्रुटि दिखेगी ही नहीं। cron के रनjournalctl -u cronमें दिखते हैं (RHEL जैसे सिस्टम में सर्विस का नामcrondहै)।
systemd वाले सिस्टम में cron का विकल्प systemd टाइमर हैं: वे आउटपुट जर्नल में लिखते हैं और छूटे हुए रन बाद में पूरे कर सकते हैं।
निष्कर्ष
शुरुआती के लिए bash स्क्रिप्ट एक फ़ाइल है, जिसकी शुरुआत shebang #!/bin/bash से होती है, उसे चलाने का अधिकार होता है और उसमें कमांड का क्रम होता है। उद्धरण चिह्नों वाले वेरिएबल, if से आर्गुमेंट की जाँच, for और while लूप, और सख़्त मोड set -euo pipefail जोड़ें, और आपको एक भरोसेमंद ऑटोमेशन टूल मिल जाएगा, जिसे cron शेड्यूल पर चलाएगा। Bash स्क्रिप्ट, एनवायरनमेंट और cron हमारे लिनक्स कोर्स में व्यवहार में सिखाए जाते हैं।
अक्सर पूछे जाने वाले प्रश्न
bash और sh में क्या अंतर है?
sh एक मानक POSIX शेल है, जबकि bash उसका विस्तारित रूप है, जिसमें एरे, डबल कोष्ठक और दूसरी सुविधाएँ हैं। bash के निर्माण वाली स्क्रिप्ट को bash से ही चलाना चाहिए, sh से नहीं।
bash स्क्रिप्ट का एक्सटेंशन क्या होना चाहिए?
Linux एक्सटेंशन नहीं देखता, इंटरप्रेटर shebang से तय होता है। <code>.sh</code> केवल एक परंपरा है, ताकि इंसान पहचान सके कि यह स्क्रिप्ट है।
स्क्रिप्ट को पासवर्ड सुरक्षित रूप से कैसे दें?
उसे आर्गुमेंट के रूप में न दें, क्योंकि आर्गुमेंट <code>ps</code> में दूसरे यूज़र को भी दिखते हैं। 600 अधिकार वाली फ़ाइल से पर्यावरण वेरिएबल पढ़ें, या <code>read -s</code> से बिना दिखाए इनपुट लें।
कैसे जाँचें कि स्क्रिप्ट root से चल रही है?
यूज़र आईडी को शून्य से तुलना करें: <code>if [[ $EUID -ne 0 ]]; then echo "root चाहिए"; exit 1; fi</code>।
SSH से बाहर निकलने के बाद भी स्क्रिप्ट चलती रहे, इसके लिए क्या करें?
<code>nohup ./script.sh &</code> इस्तेमाल करें, या tmux या screen सेशन में चलाएँ। स्थायी काम के लिए स्क्रिप्ट को systemd सर्विस बना दें।
यह विषय “Linux: с нуля до уверенного администрирования” कोर्स में अभ्यास के साथ विस्तार से समझाया गया है।
- Bash-скрипты: от команды в терминале до рабочего скрипта автоматизации
- Пакеты, окружение и первая автоматизация: apt, профиль и cron