Bash
संकेतों और सिस्टम घटनाओं पर प्रतिक्रिया करने के लिए "ट्रैप" का उपयोग करना
खोज…
वाक्य - विन्यास
- trap action sigspec ... # रन "एक्शन" सिग्नल्स की लिस्ट पर
- trap sigspec ... # ओमिटिंग एक्शन सिग्नल के लिए ट्रैप को रीसेट करता है
पैरामीटर
पैरामीटर | अर्थ |
---|---|
-p | वर्तमान में स्थापित जाल की सूची बनाएं |
-l | सूची के नाम और संबंधित संख्या को सूचीबद्ध करें |
टिप्पणियों
trap
उपयोगिता एक विशेष शेल निर्मित है। यह POSIX में परिभाषित है , लेकिन बैश कुछ उपयोगी एक्सटेंशन भी जोड़ता है।
ऐसे उदाहरण जो POSIX- संगत के साथ शुरू होते हैं #!/bin/sh
, और उदाहरण जो #!/bin/bash
शुरू होते हैं, एक bash एक्सटेंशन का उपयोग करते हैं।
सिग्नल या तो एक सिग्नल नंबर, एक सिग्नल नाम (SIG उपसर्ग के बिना), या विशेष कीवर्ड EXIT
।
POSIX द्वारा गारंटीकृत हैं:
संख्या | नाम | टिप्पणियाँ |
---|---|---|
0 | बाहर जाएं | हमेशा बाहर निकलने के कोड की परवाह किए बिना, शेल से बाहर निकलें |
1 | उच्छ्वास करो | |
2 | SIGINT | यह वह है जो ^C भेजता है |
3 | SIGQUIT | |
6 | SIGABRT | |
9 | SIGKILL | |
14 | SIGALRM | |
15 | SIGTERM | यह वह है जो डिफ़ॉल्ट रूप से kill भेजता है |
पकड़ने वाला संकेत या सीटीएल + सी
जाल सबस्क्रिप्शन के लिए रीसेट हो जाता है, इसलिए sleep
^C
(आमतौर पर छोड़ने से) द्वारा भेजे गए SIGINT
सिग्नल पर कार्य करेगी, लेकिन मूल प्रक्रिया (यानी शेल स्क्रिप्ट) नहीं होगी।
#!/bin/sh
# Run a command on signal 2 (SIGINT, which is what ^C sends)
sigint() {
echo "Killed subshell!"
}
trap sigint INT
# Or use the no-op command for no output
#trap : INT
# This will be killed on the first ^C
echo "Sleeping..."
sleep 500
echo "Sleeping..."
sleep 500
और एक वैरिएंट, जो अभी भी आपको एक सेकंड में दो बार ^C
दबाकर मुख्य कार्यक्रम छोड़ने की अनुमति देता है:
last=0
allow_quit() {
[ $(date +%s) -lt $(( $last + 1 )) ] && exit
echo "Press ^C twice in a row to quit"
last=$(date +%s)
}
trap allow_quit INT
परिचय: अस्थायी फ़ाइलों को साफ करें
आप "ट्रैप" संकेतों के लिए trap
कमांड का उपयोग कर सकते हैं; यह signal()
को पकड़ने के लिए signal()
या sigaction()
कॉल और अन्य प्रोग्रामिंग भाषाओं के बराबर शेल है।
trap
के सबसे आम उपयोगों में से एक अस्थायी फ़ाइलों को एक अपेक्षित और अप्रत्याशित दोनों निकास पर साफ करना है।
दुर्भाग्य से पर्याप्त शेल स्क्रिप्ट ऐसा नहीं करते हैं :-(
#!/bin/sh
# Make a cleanup function
cleanup() {
rm --force -- "${tmp}"
}
# Trap the special "EXIT" group, which is always run when the shell exits.
trap cleanup EXIT
# Create a temporary file
tmp="$(mktemp -p /tmp tmpfileXXXXXXX)"
echo "Hello, world!" >> "${tmp}"
# No rm -f "$tmp" needed. The advantage of using EXIT is that it still works
# even if there was an error or if you used exit.
निकास पर चलने के लिए जाल कार्य की एक सूची संचित करें।
क्या आप कभी एक अस्थायी फ़ाइल को साफ करने के लिए एक trap
जोड़ने या बाहर निकलने पर अन्य काम करना भूल गए हैं?
क्या आपने कभी एक जाल बिछाया है जो दूसरे को रद्द कर दिया है?
यह कोड एक बार में एक आइटम से बाहर निकलने पर किए जाने वाले कामों को जोड़ना आसान बनाता है, न कि आपके कोड में कहीं एक बड़ा trap
स्टेटमेंट, जिसे भूलना आसान हो सकता है।
# on_exit and add_on_exit
# Usage:
# add_on_exit rm -f /tmp/foo
# add_on_exit echo "I am exiting"
# tempfile=$(mktemp)
# add_on_exit rm -f "$tempfile"
# Based on http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
function on_exit()
{
for i in "${on_exit_items[@]}"
do
eval $i
done
}
function add_on_exit()
{
local n=${#on_exit_items[*]}
on_exit_items[$n]="$*"
if [[ $n -eq 0 ]]; then
trap on_exit EXIT
fi
}
एग्ज़िट पर बाल प्रक्रियाओं को मारना
ट्रैप अभिव्यक्तियों में व्यक्तिगत कार्य या कार्यक्रम नहीं होते हैं, वे अधिक जटिल अभिव्यक्ति भी हो सकते हैं।
jobs -p
और kill
मिलाकर, हम बाहर निकलने पर शेल की सभी स्पावर्ड चाइल्ड प्रक्रियाओं को मार सकते हैं:
trap 'jobs -p | xargs kill' EXIT
टर्मिनलों के खिड़की के आकार के परिवर्तन पर प्रतिक्रिया
एक संकेत WINCH (WINVACHange) है, जो एक टर्मिनल विंडो का आकार बदलने पर निकाल दिया जाता है।
declare -x rows cols
update_size(){
rows=$(tput lines) # get actual lines of term
cols=$(tput cols) # get actual columns of term
echo DEBUG terminal window has no $rows lines and is $cols characters wide
}
trap update_size WINCH