มีเปลือกยูนิกซ์ที่ทำหน้าที่เหมือนกันหรือไม่?


18

ฉัน (จริงๆ) มือใหม่ที่จะเขียนโปรแกรมใช้งานได้ (อันที่จริงมีเพียงการติดต่อกับมันโดยใช้ python) แต่ดูเหมือนว่าจะเป็นวิธีที่ดีสำหรับงานที่ต้องทำรายการมากในสภาพแวดล้อมของเชลล์

ฉันชอบทำสิ่งนี้:

$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]

มี Unix shell ใดบ้างที่มีคุณสมบัติประเภทนี้? หรือบางทีคุณสมบัติบางอย่างเพื่อให้เข้าถึงเชลล์ได้ง่าย (คำสั่ง, env / vars, readline, ฯลฯ ... ) จากภายใน python (ความคิดคือการใช้ล่ามแบบโต้ตอบของงูใหญ่แทนการทุบตี)

แก้ไข:

บางทีตัวอย่างเปรียบเทียบจะชี้แจง สมมติว่าฉันมีรายการประกอบด้วยdir / file :

$ FILES=( build/project.rpm build/project.src.rpm )

และฉันต้องการทำงานง่าย ๆ : คัดลอกไฟล์ทั้งหมดไปยังdist / AND ติดตั้งในระบบ (เป็นส่วนหนึ่งของกระบวนการสร้าง):

ใช้ทุบตี:

$ cp $ {files [*]} dist /
$ cd dist && rpm -Uvh $ (สำหรับ f ใน $ {files [*]}; ทำ basename $ f; เสร็จแล้ว)

ใช้วิธี "pythonic shell" (ข้อควรระวัง: นี่คือรหัสจินตภาพ):

$ cp [os.path.join ('dist', os.path.basename (ไฟล์)) สำหรับไฟล์ใน FILES] 'dist'

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

และที่สำคัญจริง ๆ แล้วจุดสำคัญ: การใช้ไวยากรณ์ / เครื่องมือ / คุณสมบัติที่ทุกคนรู้แล้ว: sh และ python

IPython เห็นว่าเป็นไปในทิศทางที่ดี แต่มันจะบวม: ถ้าชื่อ var เริ่มต้นด้วย '$' จะทำเช่นนี้ถ้า '$$' ทำเช่นนั้น มันเป็นไวยากรณ์ไม่ใช่ "ธรรมชาติ" กฎมากมายและ "การแก้ไขปัญหา" ( [ ln.upper() for ln in !ls ] -> ข้อผิดพลาดทางไวยากรณ์)


ค่อนข้างเกี่ยวข้อง: github.com/amoffat/pbs
Josh Lee


4
มีความเข้าใจมากกว่าการเขียนโปรแกรมฟังก์ชั่นเล็กน้อย หากเป้าหมายหลักของคุณคือการเขียนรหัสการทำงานฉันจะไม่ใช้ไพ ธ อนเป็นตัวอย่าง
pqnet

คำตอบ:


10

มีScheme Shellที่ใกล้กับสิ่งที่คุณกำลังมองหา ฉันไม่ได้ใช้ด้วยตัวเอง

อัปเดต:

ฉันเพิ่งติดตั้งและลองด้วยตัวเอง ดูเหมือนว่า scsh นั้นเป็นล่าม Scheme แบบโต้ตอบและภาษาสคริปต์มากกว่าเชลล์แบบโต้ตอบที่มีประโยชน์จริงๆ คุณพิมพ์ไม่ได้

echo hello

ไวยากรณ์ดูเหมือนจะเป็น

(run (echo hello))

และใช้เวลาหลายนาทีในการหา Google ตัวอย่างแรกที่นี่คือ:

gunzip < paper.tex.gz | detex | spell | lpr -Ppulp &

ซึ่งแปลเป็น:

(& (| (gunzip) (detex) (spell) (lpr -Ppulp)) (< paper.tex.gz))

แต่นั่นไม่ได้บอกวิธีเรียกใช้คำสั่ง shell อย่างง่าย

รายการคำถามที่พบบ่อยนี้พูดว่า:

4.6 ฉันสามารถใช้ scsh เป็นเชลล์แบบโต้ตอบได้หรือไม่?

ในทางเทคนิคคุณสามารถทำได้เพียงแค่เรียกใช้คำสั่ง "scsh" และคุณจะเข้าสู่เซสชัน Scheme 48 พร้อมฟังก์ชั่น scsh ทั้งหมดที่มีให้ อย่างไรก็ตามนี่ไม่เหมาะสำหรับการทำงานแบบโต้ตอบ: ไม่มีการแก้ไขบรรทัดคำสั่งไม่มีประวัติบรรทัดคำสั่งไม่มีการเติมชื่อไฟล์ / ฟังก์ชั่นไม่มีการใช้ไวยากรณ์สั้น ๆ เป็นต้น

เพื่อบรรเทาปัญหาเหล่านี้ Martin Gasbichler และ Eric Knauel ได้เขียน Commander S ซึ่งทำงานบน scsh และให้สภาพแวดล้อมแบบโต้ตอบที่สะดวกสบาย หนึ่งในคุณสมบัติใหม่ของมันคือมันสามารถเข้าใจผลลัพธ์ของคำสั่ง Unix จำนวนมากและช่วยให้ผู้ใช้สามารถเรียกดูและจัดการกับมันในรูปแบบที่มีประโยชน์ ข้อมูลเพิ่มเติมเกี่ยวกับ Commander S สามารถดูได้จากเอกสารอธิบาย: http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf คำแนะนำเกี่ยวกับวิธีการขอรับและติดตั้ง Commander S มีให้จาก เว็บไซต์ scsh: http://www.scsh.net/resources/commander-s.html

ดังนั้นอาจเป็นคำตอบที่แท้จริง


7

ในหมวดหมู่ของการตอบคำถามโดยตรงมีเชลล์ ESซึ่งมีวัตถุประสงค์เพื่อแทนที่การทำงานสำหรับ Bash และ Zsh เป็นต้น

ประการที่สองในหมวดหมู่ของการช่วยให้คุณเขียนเชลล์มาตรฐานที่ใช้งานได้มากกว่าให้ลองเรียนรู้เทคนิค pipemill:

who | while read username 
do
  cat <<EOF | grep $username
nic
mark
norman
keith
EOF
done | while read username
do
  echo "you have an answer on superuser.com" | mail -s "well done" $username
done

ในขณะที่วงแรกเป็นฟังก์ชั่นkeep(ผ่านเฉพาะค่าที่ไม่ใช่ศูนย์ที่ออกมาจากวง) และที่สองคือeach(แผนที่สำหรับผลข้างเคียงเท่านั้น)

นี่คือการเพิ่มขึ้นอย่างมากใน fp ในกระสุน

มีความเป็นไปได้ที่จะแสดงหลาย ๆ อย่างในสไตล์ fp ที่มากกว่าในเปลือกมันไม่ง่ายอย่างที่คิด ดูเหมือนว่าไม่มีความสนใจในการสร้างกระสุนที่ดีกว่าแม้ว่าเราจะใช้มันเป็นจำนวนมากก็ตาม


6

มาตรฐานหอยบอร์นสไตล์ ( sh, bash, kshฯลฯ ) แล้วให้คุณทำ:

for repo in repo1 repo2 repo3 ; do git clone $host/$repo ; done

(สังเกตความต้องการเซมิโคลอนก่อนdoและdone.) นอกจากนี้ในbashและเชลล์อื่น ๆ หาก$repoปรากฏเพียงครั้งเดียวในคำสั่งคุณสามารถเขียน:

git clone $host/{repo1,repo2,repo3}

แน่นอนและฉันจะใช้มันมาก แต่สิ่งอื่น ๆ เช่นฟังก์ชั่นแลมบ์ดา?

8
git clone $host/{repo1,repo2,repo3}ไม่ได้ทำสิ่งเดียวกันกับforวง มันจะเรียกใช้git cloneครั้งเดียวด้วยสามข้อโต้แย้ง ความจริงที่ว่าโดยพื้นฐานแล้วสิ่งเดียวกันนั้นเป็นสิ่งประดิษฐ์ของวิธีการgit cloneทำงาน ไม่จำเป็นต้องใช้กับคำสั่งอื่น ๆ (เปรียบเทียบecho foo bar bazกับecho foo; echo bar; echo bazตัวอย่าง)
Keith Thompson

@caruccio คุณสามารถใช้FUN=eval 'git clone '"$host"'$0 เพื่อกำหนดแลมบ์ดาเพื่อใช้เป็นfor repo in repo{1,2,3} ; do $FUN $repo ; done
pqnet

ปัญหาที่ใหญ่ที่สุดคือเครื่องมือ unix มักจะมีผลข้างเคียง (เช่นการเขียนลงไฟล์) ดังนั้นคุณมักจะไม่สามารถเขียนได้เหมือนที่คุณต้องการทำในภาษาที่ใช้งานได้
weberc2

2

Scheme Shell, scsh, ดีจริงๆ

ดังที่บันทึกของ Keith Thompson มันไม่มีประโยชน์ในฐานะเชลล์แบบโต้ตอบ (แม้ว่า Commander S จะดูเหมือนการทดลองที่น่าสนใจ) แต่เป็นภาษาการเขียนโปรแกรมที่ยอดเยี่ยมสำหรับบริบทที่มีการผูก POSIX ทั้งหมดมีประโยชน์ - ซึ่งรวมถึงกรณีที่คุณต้องการเรียกใช้แอปพลิเคชัน Unix อื่น ๆ เชลล์สคริปต์กว่าไม่กี่บรรทัดโหลจะเสมอรู้สึกเหมือนสับว่าคุณเขียนอย่างเรียบร้อยไม่มีsh; ในทางตรงกันข้ามไม่มีอะไรหยุดคุณเขียนโปรแกรมที่สำคัญโดยใช้ scsh

scsh มีขนาดเล็กมาก (ความกะทัดรัดเป็นทั้งจุดแข็งและจุดอ่อนของภาษาตระกูล sh) แต่มีประสิทธิภาพ

เนื่องจากมีประโยชน์และใช้งานได้จริงสำหรับงานขนาดเล็กและขนาดใหญ่ scsh จึงเป็นวิธีที่ดีในการเข้าร่วมโครงการ (แม้ว่าจะเป็นเป้าหมายของคุณคุณก็อาจตรงไปที่ Racket ในวันนี้)

ข้อดีของภาษาที่ใช้งานไม่ได้มีไว้สำหรับงานที่ต้องใช้ลิสต์มาก (แต่เนื่องจากประวัติของพวกมันพวกเขามักจะชอบลิสต์เป็นโครงสร้างข้อมูล) - มันเป็นวิธีที่มีประสิทธิภาพในการเขียนโปรแกรมเมื่อคุณดื่ม kool ที่ถูกต้อง ช่วยเหลือ

ไม่มีความหมายที่มีความหมายซึ่งเชลล์สไตล์ sh นั้นใช้งานได้และ Python ทำงานได้เฉพาะในแง่ที่ว่ามันมีฟังก์ชั่นแลมบ์ดา


2

เชลล์จำเป็นต้องแสดงออกอย่างมากซึ่งหมายความว่าคุณจะได้รับลอตจำนวนมากโดยมีบรรทัดน้อยลงโทเค็นและอื่น ๆ

เรามักจะสร้างภาษาที่แสดงออกโดยการออกแบบเพื่อวัตถุประสงค์พิเศษเช่น shells หรือ DSL เช่น R, Maple เป็นต้นและคุณจะพบว่ามีความหมายเล็กน้อยในภาษาที่ใช้งานทั่วไปเช่น C, C ++, Java เป็นต้น

Python, Perl, Ruby และอื่น ๆ เป็นภาษาที่ใช้งานทั่วไปที่มีความหมายมากกว่าในรูปแบบที่คล้ายกับเชลล์การพิมพ์แบบ Ala Duck ดังนั้น DSL จึงเชื่อมเข้าหาพวกเขา Ala Sageสำหรับคณิตศาสตร์ ไม่ดีดังนั้นสำหรับคำสั่งที่เกิดขึ้นจริง แต่เปลือก

โครงการไม่ได้เป็นสิ่งที่แสดงออกแม้ว่าคุณจะสร้าง DLS เนื่องจากวงเล็บทั้งหมด

อย่างไรก็ตามมีภาษาที่ใช้งานได้เช่น Haskell ที่มีความสามารถในการแสดงออกสูงและความสามารถที่ยอดเยี่ยมสำหรับการสร้าง DSL ความพยายามที่น่าสนใจในการสร้างเปลือกใน Haskell มีเต่าและเปลือก

ในทางปฏิบัติมีเส้นโค้งการเรียนรู้พร้อมเครื่องมือความพยายามเนื่องจากระบบประเภท Haskell ทรงพลัง แต่เข้มงวด แต่พวกเขาแสดงคำมั่นสัญญามากมาย


1

ครั้งแรกที่คุณควรจะใช้ทุกที่ที่คุณได้"${files[@]}" ${files[*]}มิฉะนั้นช่องว่างจะทำให้คุณสับสน

เชลล์นั้นใช้งานได้ดีอยู่แล้ว ถ้าคุณคิดว่าในแง่ของการส่งออกรายการเป็นข้อความของสายแล้วgrepคือfilter, xargsเป็นmapฯลฯ ท่อมีการทำงานมาก

เชลล์ไม่ได้รับการยอมรับว่าเป็นสภาพแวดล้อมในการเขียนโปรแกรมที่เป็นมิตร แต่ก็เหมาะสมกับการใช้งานแบบอินเตอร์แอคทีฟมากกว่า Python และมีคุณสมบัติที่ดีมากที่ API และ UI เหมือนกัน - เรียนรู้ทั้งสองอย่างพร้อมกัน

ผมไม่เข้าใจว่าทำไมคุณพบว่ากว่าที่จะcp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist' cp "${FILES[@]}" distหลังมีการพิมพ์น้อยกว่ามาก


0

ไม่ทราบว่ามันเป็น "ใช้งานได้" แต่ยังมีrcอีกด้วยซึ่งกระดาษ scshกล่าวถึง มันเป็นรุ่นก่อนหน้าของ es

บน Linux Mint (และอาจเป็น Debian, Ubuntu ... ) คุณสามารถลองใช้ได้

sudo apt-get install rc
man rc
rc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.