कुछ बैश ट्रिक्स जिनका उपयोग मैं कमांड से वेरिएबल्स सेट करने के लिए करता हूं
दूसरा संपादन २०१ at-०२-१२: एक अलग तरह से जोड़ा गया, लंबे समय से चल रहे कार्यों के लिए इसके नीचे खोज करें !
2018-01-25 संपादित करें: एक नमूना फ़ंक्शन जोड़ा (डिस्क उपयोग के बारे में चर आबादी के लिए)
पहला सरल, पुराना और संगत तरीका
myPi=`echo '4*a(1)' | bc -l`
echo $myPi
3.14159265358979323844
अधिकतर संगत, दूसरा तरीका
चूंकि घोंसला भारी हो सकता है, इसके लिए कोष्ठक लागू किया गया था
myPi=$(bc -l <<<'4*a(1)')
नेस्टेड नमूना:
SysStarted=$(date -d "$(ps ho lstart 1)" +%s)
echo $SysStarted
1480656334
एक से अधिक वेरिएबल पढ़ना ( बाशिम के साथ )
df -k /
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/dm-0 999320 529020 401488 57% /
अगर मैं सिर्फ एक इस्तेमाल किया मूल्य चाहते हैं :
array=($(df -k /))
आप एक सरणी चर देख सकते हैं :
declare -p array
declare -a array='([0]="Filesystem" [1]="1K-blocks" [2]="Used" [3]="Available" [
4]="Use%" [5]="Mounted" [6]="on" [7]="/dev/dm-0" [8]="999320" [9]="529020" [10]=
"401488" [11]="57%" [12]="/")'
फिर:
echo ${array[9]}
529020
लेकिन मुझे यह पसंद है:
{ read foo ; read filesystem size using avail prct mountpoint ; } < <(df -k /)
echo $using
529020
पहला हेडर लाइन को छोड़read foo
देगा , लेकिन केवल एक कमांड में, आप 7 अलग-अलग चर को पॉप्युलेट करेंगे :
declare -p avail filesystem foo mountpoint prct size using
declare -- avail="401488"
declare -- filesystem="/dev/dm-0"
declare -- foo="Filesystem 1K-blocks Used Available Use% Mounted on"
declare -- mountpoint="/"
declare -- prct="57%"
declare -- size="999320"
declare -- using="529020"
या और भी:
{ read foo ; read filesystem dsk[{6,2,9}] prct mountpoint ; } < <(df -k /)
declare -p mountpoint dsk
declare -- mountpoint="/"
declare -a dsk=([2]="529020" [6]="999320" [9]="401488")
... साहचर्य सरणियों के साथ भी काम करेंगे :read foo disk[total] disk[used] ...
कुछ चर को पॉप्युलेट करने के लिए नमूना समारोह:
#!/bin/bash
declare free=0 total=0 used=0
getDiskStat() {
local foo
{
read foo
read foo total used free foo
} < <(
df -k ${1:-/}
)
}
getDiskStat $1
echo $total $used $free
नोट: declare
लाइन की आवश्यकता नहीं है, सिर्फ पठनीयता के लिए।
के बारे में sudo cmd | grep ... | cut ...
shell=$(cat /etc/passwd | grep $USER | cut -d : -f 7)
echo $shell
/bin/bash
(कृपया बेकार से बचें cat
! तो यह सिर्फ एक कांटा कम है:
shell=$(grep $USER </etc/passwd | cut -d : -f 7)
सभी पाइप ( |
) का अर्थ है कांटे। जहां एक और प्रक्रिया को चलाना होता है, डिस्क पर पहुंच, पुस्तकालयों पर कॉल आदि।
तो sed
नमूने के लिए उपयोग करते हुए , केवल एक कांटा के लिए उपप्रकार को सीमित करेगा :
shell=$(sed </etc/passwd "s/^$USER:.*://p;d")
echo $shell
और बाशिस्म के साथ :
लेकिन कई कार्यों के लिए, ज्यादातर छोटी फाइलों पर, बैश खुद ही काम कर सकता था:
while IFS=: read -a line ; do
[ "$line" = "$USER" ] && shell=${line[6]}
done </etc/passwd
echo $shell
/bin/bash
या
while IFS=: read loginname encpass uid gid fullname home shell;do
[ "$loginname" = "$USER" ] && break
done </etc/passwd
echo $shell $loginname ...
परिवर्तनशील बंटवारे के बारे में आगे ...
मेरे जवाब पर एक नज़र डालें कि मैं बैश में एक सीमांकक पर एक स्ट्रिंग कैसे विभाजित करूं?
वैकल्पिक: लंबे समय से चल रहे कार्यों का उपयोग करके कांटे कम करना
2 संपादित करें 2018-02-12:
जैसे कई कांटे को रोकने के लिए
myPi=$(bc -l <<<'4*a(1)'
myRay=12
myCirc=$(bc -l <<<" 2 * $myPi * $myRay ")
या
myStarted=$(date -d "$(ps ho lstart 1)" +%s)
mySessStart=$(date -d "$(ps ho lstart $$)" +%s)
यह काम ठीक है, लेकिन कई कांटे चलाना भारी और धीमा है।
और आदेश देता है date
और bc
कई ऑपरेशन कर सकता है, लाइन से लाइन !!
देख:
bc -l <<<$'3*4\n5*6'
12
30
date -f - +%s < <(ps ho lstart 1 $$)
1516030449
1517853288
इसलिए हम प्रत्येक अनुरोध के लिए एक नया कांटा शुरू करने के बिना, कई काम करने के लिए एक लंबी चलने वाली पृष्ठभूमि प्रक्रिया का उपयोग कर सकते हैं ।
हमें इसे ठीक से करने के लिए कुछ फ़ाइल डिस्क्रिप्टर और पोज़ की आवश्यकता है:
mkfifo /tmp/myFifoForBc
exec 5> >(bc -l >/tmp/myFifoForBc)
exec 6</tmp/myFifoForBc
rm /tmp/myFifoForBc
(बेशक, एफडी 5
और 6
अप्रयुक्त होना है!) ... वहां से, आप इस प्रक्रिया का उपयोग कर सकते हैं:
echo "3*4" >&5
read -u 6 foo
echo $foo
12
echo >&5 "pi=4*a(1)"
echo >&5 "2*pi*12"
read -u 6 foo
echo $foo
75.39822368615503772256
एक समारोह में newConnector
आपको मेरा newConnector
फ़ंक्शन GitHub.Com या मेरी स्वयं की साइट पर मिल सकता है (नोट GitHub पर: मेरी साइट पर दो हैं। फ़ंक्शन और डेमो को एक फ़ाइल में बंडल किया गया है जिसे उपयोग के लिए खट्टा किया जा सकता है या बस डेमो के लिए चलाया जा सकता है।)
नमूना:
. shell_connector.sh
tty
/dev/pts/20
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
29019 pts/20 Ss 0:00 bash
30745 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
newConnector /usr/bin/bc "-l" '3*4' 12
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
29019 pts/20 Ss 0:00 bash
30944 pts/20 S 0:00 \_ /usr/bin/bc -l
30952 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
declare -p PI
bash: declare: PI: not found
myBc '4*a(1)' PI
declare -p PI
declare -- PI="3.14159265358979323844"
फ़ंक्शन myBc
आपको सरल सिंटैक्स के साथ पृष्ठभूमि कार्य का उपयोग करने देता है, और तिथि के लिए:
newConnector /bin/date '-f - +%s' @0 0
myDate '2000-01-01'
946681200
myDate "$(ps ho lstart 1)" boottime
myDate now now ; read utm idl </proc/uptime
myBc "$now-$boottime" uptime
printf "%s\n" ${utm%%.*} $uptime
42134906
42134906
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
29019 pts/20 Ss 0:00 bash
30944 pts/20 S 0:00 \_ /usr/bin/bc -l
32615 pts/20 S 0:00 \_ /bin/date -f - +%s
3162 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
वहाँ से, यदि आप पृष्ठभूमि की किसी एक प्रक्रिया को समाप्त करना चाहते हैं, तो आपको बस इसकी fd को बंद करना होगा :
eval "exec $DATEOUT>&-"
eval "exec $DATEIN>&-"
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
4936 pts/20 Ss 0:00 bash
5256 pts/20 S 0:00 \_ /usr/bin/bc -l
6358 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
जिसकी आवश्यकता नहीं है, क्योंकि मुख्य प्रक्रिया समाप्त होने पर सभी fd बंद हो जाते हैं।