เทคนิคบางอย่างเกี่ยวกับการเปลี่ยนเส้นทาง
ลักษณะเฉพาะบางอย่างของไวยากรณ์นี้อาจมีพฤติกรรมที่สำคัญ มีบางตัวอย่างเล็ก ๆ น้อย ๆ เกี่ยวกับการเปลี่ยนเส้นทางเป็นSTDERR
, STDOUT
และการขัดแย้งการสั่งซื้อ
1 - เขียนทับหรือต่อท้าย?
สัญลักษณ์>
หมายถึงการเปลี่ยนเส้นทาง
>
หมายถึงส่งไปยังไฟล์ที่เสร็จสมบูรณ์ทั้งหมดเขียนทับเป้าหมายหากมีอยู่ (ดูnoclobber
คุณสมบัติทุบตีที่# 3 ในภายหลัง)
>>
หมายถึงการส่งนอกจากนี้จะผนวกเข้ากับเป้าหมายหากมีอยู่
ไม่ว่าในกรณีใดไฟล์จะถูกสร้างขึ้นหากไม่มีอยู่
2 - บรรทัดคำสั่งเชลล์ขึ้นอยู่กับการสั่งซื้อ !!
สำหรับการทดสอบสิ่งนี้เราจำเป็นต้องมีคำสั่งง่ายๆซึ่งจะส่งบางสิ่งบางอย่างในเอาต์พุต :
$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
(คาดว่าคุณไม่มีไดเรกทอรีชื่อ/tnt
แน่นอน;) เรามีมัน !!
ดังนั้นเรามาดู:
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1
$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory
บรรทัดคำสั่งสุดท้ายทิ้งSTDERR
ไปที่คอนโซลและดูเหมือนจะไม่เป็นพฤติกรรมที่คาดหวัง ... แต่ ...
หากคุณต้องการให้การโพสต์ตัวกรองบางอย่างเกี่ยวกับการส่งออกหนึ่งอื่น ๆ หรือทั้งสองอย่าง:
$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'
$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
โปรดสังเกตว่าบรรทัดคำสั่งสุดท้ายในย่อหน้านี้เหมือนกับในย่อหน้าก่อนหน้าซึ่งที่ฉันเขียนดูเหมือนจะไม่เป็นพฤติกรรมที่คาดหวัง (ดังนั้นนี่อาจเป็นพฤติกรรมที่คาดหวัง)
มีเทคนิคเล็กน้อยเกี่ยวกับการเปลี่ยนเส้นทางสำหรับ
การดำเนินการที่แตกต่างกันในผลลัพธ์ทั้งสอง :
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
หมายเหตุ: คำอธิบายถึงจะเกิดขึ้นเองตามธรรมชาติเพราะ&9
) 9>&2
ภาคผนวก: nota! ด้วยเวอร์ชั่นใหม่ของทุบตี( >4.0
) มีคุณสมบัติใหม่และไวยากรณ์ที่เซ็กซี่ยิ่งขึ้นสำหรับการทำสิ่งนี้:
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
และสุดท้ายสำหรับการจัดรูปแบบเอาต์พุตแบบเรียงซ้อนเช่น:
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
ภาคผนวก: nota! ไวยากรณ์ใหม่ที่เหมือนกันทั้งสองวิธี:
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
ที่STDOUT
ผ่านตัวกรองที่เฉพาะเจาะจงSTDERR
ไปยังอีกและในที่สุดทั้งสองออกไปรวมกันผ่านตัวกรองคำสั่งที่สาม
3 - คำเกี่ยวกับnoclobber
ตัวเลือกและ>|
ไวยากรณ์
เกี่ยวกับการเขียนทับ :
ในขณะที่set -o noclobber
สั่งให้ bash ไม่เขียนทับไฟล์ใด ๆ ที่มีอยู่>|
ไวยากรณ์จะให้คุณผ่านข้อ จำกัด นี้:
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:15 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:19 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:21 CET 2013
ไฟล์ถูกเขียนทับทุกครั้งตอนนี้:
$ set -o noclobber
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
ผ่านด้วย>|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
การยกเลิกการตั้งค่าตัวเลือกนี้และ / หรือสอบถามว่าได้ตั้งค่าไว้แล้ว
$ set -o | grep noclobber
noclobber on
$ set +o noclobber
$ set -o | grep noclobber
noclobber off
$ date > $testfile ; cat $testfile
Mon Jan 7 13:24:27 CET 2013
$ rm $testfile
4 - เคล็ดลับสุดท้ายและอื่น ๆ ...
สำหรับการเปลี่ยนเส้นทางเอาต์พุตทั้งสองจากคำสั่งที่กำหนดเราจะเห็นว่าไวยากรณ์ที่ถูกต้องอาจเป็น:
$ ls -ld /tmp /tnt >/dev/null 2>&1
สำหรับกรณีพิเศษนี้จะมีไวยากรณ์ทางลัด: &>
... หรือ>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
หมายเหตุ: หาก2>&1
มีอยู่1>&2
ก็เป็นไวยากรณ์ที่ถูกต้องเช่นกัน:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- ตอนนี้ฉันจะให้คุณคิดถึง:
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
4c- หากคุณกำลังสนใจในการเพิ่มเติมข้อมูล
คุณสามารถอ่านคู่มือละเอียดได้โดยกดปุ่ม:
man -Len -Pless\ +/^REDIRECTION bash
ใน ทุบตี คอนโซล ;-)