ซอร์สสคริปต์มีปัญหากับ subshell ตัวอย่างแรกคุณอาจไม่ต้องการ subshell แต่เราไม่รู้ว่ามีอะไรซ่อนอยู่ภายใต้ "Some more action" คำตอบยอดนิยมมีบั๊กซ่อนอยู่ซึ่งจะเพิ่ม I / O และจะไม่ทำงานกับ subshell เพราะจะคืนค่า couter ภายในลูป
อย่าใส่เครื่องหมาย '\' เสริมเพราะจะแจ้งให้ล่าม bash ทราบเกี่ยวกับความต่อเนื่องของบรรทัด ฉันหวังว่ามันจะช่วยคุณหรือใครก็ได้ แต่ในความคิดของฉันสคริปต์นี้ควรถูกแปลงเป็นสคริปต์ AWK อย่างสมบูรณ์หรือเขียนใหม่เป็น python โดยใช้ regexp หรือ perl แต่ความนิยม perl ในช่วงหลายปีที่ผ่านมาลดลง ดีกว่าทำด้วย python
เวอร์ชันที่แก้ไขโดยไม่มี subshell:
#!/bin/bash
WFY_PATH=/var/log/nginx
WFY_FILE=error.log
COUNTER=0
grep 'GET /log_' $WFY_PATH/$WFY_FILE | grep 'upstream timed out' |\
awk -F ', ' '{print $2,$4,$0}' |\
awk '{print "http://example.com"$5"&ip="$2"&date="$7"&time="$8"&end=1"}' |\
awk -F '&end=1' '{print $1"&end=1"}' |\
#( #unneeded bracket
while read WFY_URL
do
echo $WFY_URL #Some more action
COUNTER=$((COUNTER+1))
done
# ) unneeded bracket
echo $COUNTER # output = 0
เวอร์ชันที่มี subshell หากจำเป็นจริงๆ
#!/bin/bash
TEMPFILE=/tmp/$$.tmp #I've got it from the most popular answer
WFY_PATH=/var/log/nginx
WFY_FILE=error.log
COUNTER=0
grep 'GET /log_' $WFY_PATH/$WFY_FILE | grep 'upstream timed out' |\
awk -F ', ' '{print $2,$4,$0}' |\
awk '{print "http://example.com"$5"&ip="$2"&date="$7"&time="$8"&end=1"}' |\
awk -F '&end=1' '{print $1"&end=1"}' |\
(
while read WFY_URL
do
echo $WFY_URL #Some more action
COUNTER=$((COUNTER+1))
done
echo $COUNTER > $TEMPFILE #store counter only once, do it after loop, you will save I/O
)
COUNTER=$(cat $TEMPFILE) #restore counter
unlink $TEMPFILE
echo $COUNTER # output = 0