การกระจายสคริปต์: ฉันควรใช้ / bin / gawk หรือ / usr / bin / gawk สำหรับ shebang หรือไม่


12

เหยี่ยวใน / bin หรือ / usr / bin เป็นปกติหรือไม่? ฉันจะไปด้วย#!/usr/bin/env gawkแต่แล้วฉันก็ไม่สามารถใช้การโต้แย้ง #!/bin/gawk -fตอนนี้ผมใช้ สคริปต์ยาวมากและมีคำพูดเดียวจำนวนมากและใช้งานได้กับ stdin

คู่มือ GNU Awk มีส่วน 1.1.4 โปรแกรมปฏิบัติการ awkที่ใช้ #! / bin / awk ในตัวอย่าง แต่จะพูดต่อไปว่า:

โปรดทราบว่าในระบบจำนวนมากawkอาจพบได้ในแทนใน/usr/bin /binCaveat Emptor

คนส่วนใหญ่ทำอะไร ฉันได้อ่านsed แล้วจะถือว่าเป็นมาตรฐานใน / binในขณะที่ perl นั้นควรจะเป็นมาตรฐานใน / usr / bin (หน้าเดียวกับ sed link แต่พวกเขาจะไม่ให้ฉันสร้างลิงค์ที่สามสำหรับโพสต์นี้) แล้ว awk / gawk ล่ะ? ไม่มีใครรู้ว่าสิ่งที่เป็นเรื่องธรรมดาหรือเป็นที่นิยมมากขึ้น?


ทำไมคุณใช้-f? ยังไม่/bin/gawkพอเหรอ นอกจากนี้อาจเกี่ยวข้อง
terdon

คำตอบ:


7

shebang ไม่ได้หมายความว่าจะเป็นที่มีความยืดหยุ่น อาจมีบางกรณีที่การใช้พารามิเตอร์ตัวที่สองทำงานได้ฉันคิดว่า FreeBSD เป็นหนึ่งในนั้น

เพ่งพิศและสาธารณูปโภคส่วนใหญ่ที่มาพร้อมกับระบบปฏิบัติการที่คาดว่าจะ/usr/bin/มา

ใน UNIX รุ่นเก่าเป็นเรื่องปกติที่จะ/usr/ติดตั้งผ่าน NFS หรือสื่อที่ราคาไม่แพงเพื่อประหยัดพื้นที่ดิสก์และค่าใช้จ่ายต่อเวิร์กสเตชัน /bin/ก็ควรที่จะมีทุกอย่างที่จำเป็นในการบูตในโหมดผู้เดียว เนื่องจาก/usr/ไม่ได้ติดตั้งบนสื่อที่เชื่อถือได้/bin/รวมยูทิลิตี้เพียงพอที่จะทำให้มันเป็นมิตรเพียงพอสำหรับการจัดการทั่วไปและการแก้ไขปัญหา

สิ่งนี้ได้รับการสืบทอดใน Linux ในขั้นต้น แต่เนื่องจากพื้นที่ดิสก์ไม่มีปัญหาอีกต่อไปและในกรณีส่วนใหญ่/usr/อยู่ในระบบไฟล์รูทแนวโน้มปัจจุบันคือการย้ายทุกอย่างใน/usr/bin(อย่างน้อยในโลก Linux) ดังนั้นยูทิลิตี้ส่วนใหญ่ที่ติดตั้งโดย distro คาดว่าจะพบที่นั่น แม้ระบบสาธารณูปโภคขั้นพื้นฐานมากที่สุดเช่นcp, rm, lsฯลฯ (ดียังไม่ได้)

เกี่ยวกับตัวเลือก Shebang ตามเนื้อผ้านี่เป็นสิ่งที่ผู้ดูแลระบบหรือผู้ใช้ต้องแก้ไขตามสภาพแวดล้อมของพวกเขา สำหรับทุกนักพัฒนารู้ในระบบของคนอื่นล่ามอาจจะเป็นที่ใดก็ได้ในระบบแฟ้ม (เช่น/usr/local/bin, /opt/gawk-4.0.1/bin) สคริปต์ที่จัดแพคเกจอย่างเหมาะสม (rpm, deb ฯลฯ ) มาพร้อมกับการพึ่งพาแพ็คเกจ distro (เช่นล่ามมีตำแหน่งที่ทราบ) หรือสคริปต์การตั้งค่าที่ติดตั้ง hashbang ที่เหมาะสมระหว่างการติดตั้ง


14

หากคุณไม่จำเป็นต้องส่งอาร์กิวเมนต์ไปยังคำสั่งก็#!/usr/bin/env gawkเป็นวิธีที่จะไป แต่เมล็ดจำนวนมาก (รวมถึง Linux) ยอมรับเฉพาะอาร์กิวเมนต์เดียวกับโปรแกรม shebang

มิฉะนั้นคุณสามารถสร้างโปรแกรมหลายภาษาที่เป็นทั้ง wrapper เชลล์และสคริปต์ awk นี่คือหนึ่งใน awk

#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here

การแยกวิเคราะห์เชลล์:

  • true + /;- คำสั่งtrue(ซึ่งไม่ทำอะไรเลย) กับสองเฉื่อยข้อโต้แย้งและ+/
  • gawkเรียกร้องให้ นี่อาจเป็นตัวอย่างข้อมูลเชลล์ที่ไม่มีบรรทัดใหม่และตำแหน่งที่เขียนทับ\/(เชลล์ไม่คำนึงถึงยกเว้นราคาที่อยู่ภายใน)
    การเรียกใช้execเพื่อแทนที่เชลล์ด้วย gawk แทนการดำเนินการ gawk เป็น subprocess
  • exit;- ออกจากเชลล์ในกรณีที่ไม่พบ gawk สิ่งใดหลังจากนั้นจะถูกละเว้นยกเว้นว่าควรเป็นไวยากรณ์ของเชลล์ที่ถูกต้องในกรณีที่เชลล์พยายามแยกวิเคราะห์ทั้งบรรทัดก่อนเริ่มดำเนินการ

การแยกวิเคราะห์ awk:

  • บิตระหว่างเครื่องหมายทับคือการแสดงออกปกติ
  • true + /REGEX/- เงื่อนไข trueเป็นตัวแปรที่ไม่ได้กำหนดดังนั้นค่าตัวเลขจึงเป็น 0 ไม่ใช่ว่ามันสำคัญ
  • {} - ถ้าเงื่อนไขดังกล่าวคงอยู่อย่าทำอะไรเลย

5

วิธีแก้ปัญหาที่เสนอโดย Gilles นั้นเป็นวิธีที่ดีมาก (ในที่สุดก็มีชื่อเสียงในการลงคะแนนในโพสต์ของเขา :))

ในกรณีใด ๆ เท่าที่ผมเข้าใจexecคำสั่งก็จะทำให้ทันทีหลังจากที่มันไม่จำเป็นไม่สามารถเข้าถึงได้จริงเป็นกระบวนการเปลือกจะถูกแทนที่โดยexitawk

นอกจากนี้เพื่อให้awkสคริปต์สามารถเข้าถึงพารามิเตอร์การเรียกใช้ฉันจะแนะนำการเปลี่ยนแปลงบางอย่างในวิธีแก้ปัญหาที่เสนอ:

#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here

-a "$0"ช่วยให้สคริปต์เพื่อให้มีการเข้าถึงชื่อภาวนาของตนมิฉะนั้นมันก็จะได้รับawkหรือgawkเมื่อเข้าถึงARGV[0]ตัวแปร ในทำนองเดียวกันการ"$@"อนุญาตให้สคริปต์เข้าถึงพารามิเตอร์ที่เหลืออยู่ในARGV[1...N]อาร์เรย์และ--ก่อนหน้านี้จะช่วยให้สคริปต์ที่จะได้รับการ-<something>ขัดแย้งโดยไม่ต้องเพ่งพิศตีความพวกเขามีความหมายสำหรับมัน

สิ่งหนึ่งที่ต้องจำ / พิจารณาคือการเพิ่มexit(0);คำสั่งในตอนท้ายของBEGIN { ... }บล็อกของawkโปรแกรมสคริปต์มิฉะนั้นawkจะคุกคามพารามิเตอร์ทั้งหมดที่ส่งผ่านไปยังสคริปต์เป็นไฟล์อินพุต (โปรดทราบว่ามันไม่ต้องทำอะไรเลยด้วยexitคำสั่งที่เราลบออกจากtrue + ...บรรทัดนี่เป็นคำสั่งเชลล์ที่ไม่สามารถเข้าถึงได้ในขณะที่การออกที่แนะนำนี้อยู่ในรหัส awk)


exit(0)เป็นประโยชน์อย่างมาก! นอกจากนี้สำหรับผู้ใช้งาน macos ให้ดูส่วนสำคัญนี้: awbang แบบพกพาที่ดีไม่ใช่เรื่องง่ายที่จะหา
เชมัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.