Herhangi bir kabuk üzerinde çalışacak kabuk betikleri yazma


19

Ben sadece kabuk komut dosyası içine derinleşmeye başladım ve ben her zaman sadece bir dosyaya benim komut dosyası attı, işaretlenmiş chmod +xve sonra yaptım /path/to/script.shve yorumlayıcı varsayılan ne olursa olsun, onunla zsh olduğunu varsaydım çünkü Kabuğum için kullandım. Görünüşe göre /bin/shbetiği bir zsh isteminden çalıştırsam bile varsayılan olarak görünüyor , çünkü betiğime zsh'ye özgü şeyler koymaya başladım ve çalıştırmadıkça başarısız oluyor zsh /path/to/script.sh.

Konuya ulaşmak için, benim sorularım:

  1. #!/path/to/shellBaşlangıçta hiçbir shebang satırı ( ) olmadığında hangi kabuk komut dosyalarını yürütür ? Varsayıyorum /bin/shama onaylayamıyorum.
  2. Herhangi bir platformda çalıştırılacak olan kabuk betikleri yazma açısından "en iyi uygulamalar" olarak kabul edilen nedir? (tamam, bu bir tür açık uçlu)
  3. Zsh'ı kullanmaya çalışan ve zsh yoksa bash'a geri dönen bir komut dosyası yazmak mümkün müdür? Aşağıdaki gibi iki shebang satır koyarak denedim, ama sadece bad interpreter: /bin/zsh: no such file or directoryzsh olmadan bir makinede denemek dışarı ile hataları .

    #!/bin/zsh

    #!/bin/bash

Yanıtlar:


26

Başlangıçta hiçbir shebang satırı (#! / Path / to / shell) olmadığında hangi kabuk komut dosyalarını yürütür? / Bin / sh varsayıyorum ama onaylayamıyorum.

Kesin davranış programına bağlıdır böylece çekirdek tür senaryo ve getiri yürütmek reddediyor ENOEXEC, böyle bir komut dosyasını çalıştırın gelen .

  • bash 4.2.39 - kendini kullanır
  • busybox-ash 1.20.2 - kendini kullanır
  • tire 0.5.7 - çalışır / bin / sh
  • balık 1.23.1 - ENOEXEC'ten şikayetçi, sonra yanlış dosyayı suçluyor
  • AT&T ksh 93u + 2012.08.01 - kendini kullanır
  • mksh R40f - çalışır / bin / sh
  • pdksh 5.2.14 - çalışır / bin / sh
  • sh-heirloom 050706 - kendini kullanır
  • tcsh 6.18.01 - çalışır / bin / sh
  • zsh 5.0.0 - çalışır / bin / sh
  • cmd.exe 5.1.2600 - komik görünüyor.

In glibc'nin , fonksiyonlar execv()veya execve()sadece ENOEXEC döner. Ancak execvp()bu hata kodunu gizler ve otomatik olarak / bin / sh komutunu çağırır. (Bu, exec'de (3p) belgelenmiştir .)

Herhangi bir platformda çalıştırılacak olan kabuk betikleri yazma açısından "en iyi uygulamalar" olarak kabul edilen nedir? (tamam, bu bir tür açık uçlu)

Ya shPOSIX tanımlı özelliklere sadık kalın ya da sadece tam bash'a (yaygın olarak kullanılabilir) gidin ve dağıtırsanız gereksinimlerinizden bahsedin.

(Şimdi düşündüğümde, Perl - veya belki de Python - daha iyi bir sözdizimine sahip olmaktan bahsetmiyorum bile daha taşınabilir olurdu.)

Daima mesele hattını ekleyin. Bash veya zsh kullanıyorsanız #!/usr/bin/env bash, kabuğun yolunu kodlamak yerine kullanın . (Ancak, POSIX kabuğunun olduğu garanti edilir /bin/sh, bu envdurumda atlayın .)

(Ne yazık ki, /bin/shher zaman aynı bile değildir. GNU autoconf programı birçok farklı tuhaflıkla uğraşmak zorundadır .)

Zsh'ı kullanmaya çalışan ve zsh yoksa bash'a geri dönen bir komut dosyası yazmak mümkün müdür? Aşağıdaki gibi iki shebang satır koyarak denedim, ama sadece kötü yorumlayıcı ile hatalar : / bin / zsh: zsh olmadan bir makinede denerseniz böyle bir dosya veya dizin yok .

Sadece bir shebang hattı olabilir; yeni satır karakterinden sonraki her şey çekirdek tarafından bile okunmaz ve kabuklar tarafından yorum olarak ele alınır.

Şu şekilde çalışan , hangi kabuğun kullanılabilir olduğunu kontrol eden ve sonuca bağlı olarak veya çalıştıran bir komut dosyası yazmak mümkündür . Ancak, bash ve zsh tarafından kullanılan sözdizimi çeşitli yerlerde o kadar farklı ki, bunu kendi akıl sağlığınız için yapmanızı tavsiye etmem .#!/bin/shexec zsh "$0" "$@"exec bash "$0" "$@"


1
ENOEXEC aldığında her bir kabuğun gerçekte ne aradığını nasıl izlediniz?
swrobel

2
@SWrobel: Kullanımı strace -f -e fork,clone,execve. Bazı mermiler /bin/shbaşarısızlıktan sonra idam edildi; diğerleri senaryoyu kendileri yorumladılar.
Grawity

1
@SWrobel: Başka bir yöntem, oluşan bir komut dosyası çalıştırmaktır readlink /proc/$$/exe.
Grawity


1
İçin cshve tcshsenaryo ile başlar olsun, davranış bağlıdır #(kendileri yerine sh çağırmak bu durumda onlar senaryoyu yorumlama). Bu, csh'in yorumları desteklediği, ancak Bourne kabuğunu desteklemediği zamana kadar gider, bu yüzden #bir csh betiği olduğuna dair bir ipucu oldu.
sch

2

1) İçinde bulunduğunuz kabuk (hangi kabuk olursa olsun)

2) Aynı kabuk tipine (bash / dash / ash / csh / lezzetiniz ne olursa olsun) sadık kalın ve "desteklenen platformlarınızın" varsayılan olarak kullanmak istediğiniz kabuğu kurduğundan emin olun. Ayrıca, sistemlerde yaygın olarak bulunan komutları kullanmaya çalışın. Makineye özgü seçeneklerden kaçının.

3) Gerçekten bir "if-then-else" mantığı yoktur interpreter directive. Desteklemek istediğiniz tüm sistemlerde bulunması gereken bir kabuk belirtmelisiniz ... yani #!/bin/bashveya #!/bin/shkomut dosyanız tüm kabuklarda oldukça genel olduğu sürece bir genel belirtmelisiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.