Unix konsolunda veya Mac terminalinde kabuk komut dosyası nasıl çalıştırılır?


507

Biliyorum, unut ve tekrar öğren. Yazma zamanı.


15
itibar istasyonuna upvote tren tüm yol yazma
DivideByZer0

sadece orada var o müthiş hata hayranım upvote olmayacak!
BRHSM

Yanıtlar:


942

Yürütülemeyen bir shkomut dosyasını çalıştırmak için şunu kullanın:

sh myscript

Yürütülemeyen bir bashkomut dosyasını çalıştırmak için şunu kullanın:

bash myscript

Bir yürütülebilir dosyayı başlatmak için (yürütülebilir izinli herhangi bir dosyadır); sadece yoluyla belirtirsiniz:

/foo/bar
/bin/bar
./bar

Bir komut dosyasını yürütülebilir yapmak için gerekli izni verin:

chmod +x bar
./bar

Bir dosya yürütülebilir olduğunda, çekirdek nasıl çalıştırılacağını bulmaktan sorumludur. İkili olmayan dosyalar için, bu dosyanın ilk satırına bakarak yapılır. Şunları içermelidir hashbang:

#! /usr/bin/env bash

Hashbang çekirdeğe hangi programı çalıştırdığını söyler (bu durumda komut /usr/bin/envargümanla çalıştırılır bash). Ardından, komut dosyasına sonraki bağımsız değişkenler olarak verdiğiniz tüm bağımsız değişkenlerle birlikte programa (ikinci bağımsız değişken olarak) geçirilir.

Bu , yürütülebilir her komut dosyasının bir hashbang olması gerektiği anlamına gelir . Böyle olmazsa, sen ne çekirdek söylemediğin olduğunu ve bu nedenle çekirdek onu yorumlama kullanmak ne programı bilmiyor. Olabilir bash, perl, python, sh, başka bir şey. (Gerçekte, çekirdek dosyayı yorumlamak için genellikle kullanıcının varsayılan kabuğunu kullanır; bu çok tehlikelidir, çünkü doğru yorumlayıcı olmayabilir veya bir kısmını ayrıştırabilir, ancak olgu arasında shve bash).

Hakkında bir not /usr/bin/env

En yaygın olarak, karma patlamalarını şu şekilde görürsünüz:

#!/bin/bash

Sonuç olarak, çekirdek /bin/bashkomut dosyasını yorumlamak için programı çalıştıracaktır . Ne yazık ki, bashher zaman varsayılan olarak gönderilmez ve her zaman mevcut değildir /bin. Linux makinelerde genellikle, veya bashgibi çeşitli konumlarda gemilerin bulunduğu bir dizi başka POSIX makinesi vardır ./usr/xpg/bin/bash/usr/local/bin/bash

Taşınabilir bir bash betiği yazmak için, bashprogramın yerini kodlamaya güvenemeyiz . POSIX zaten bununla başa çıkmak için bir mekanizmaya sahiptir: PATH. Buradaki fikir, programlarınızı içinde bulunduğunuz dizinlerden birine kurmanız PATHve sistemin programınızı ismiyle çalıştırmak istediğinizde bulabilmesidir.

Ne yazık ki, sen olamaz sadece bunu:

#!bash

Çekirdek (bazıları PATHsizin için ) arama yapmaz . Buna PATHrağmen sizin için arama yapabilen bir program var env. Neyse ki, neredeyse tüm sistemlerde envyüklü bir program var /usr/bin. Bu yüzden, kodunuzu yorumlayabilmesi için envbir PATHarama yapan bashve çalıştıran sabit kodlu bir yol kullanmaya başlarız :

#!/usr/bin/env bash

Bu yaklaşımın bir dezavantajı vardır: POSIX'e göre, hashbang'ın bir argümanı olabilir . Bu durumda, programın bashargümanı olarak kullanırız env. Bu, argümanları iletmek için boş alanımız olmadığı anlamına gelir bash. Dolayısıyla #!/bin/bash -exu, bu şemaya benzer bir şeyi dönüştürmenin yolu yoktur . Bunun set -exuyerine hashbang'ın arkasına koymalısın.

Bu yaklaşımın başka bir avantajı daha vardır: Bazı sistemler bir ile birlikte gelebilir /bin/bash, ancak kullanıcı bundan hoşlanmayabilir, buggy veya modası geçmiş bulabilir ve bashbaşka bir yere kendi yüklemiş olabilir . Bu genellikle Apple'ın modası geçmiş /bin/bashbir ürünü gönderdiği ve kullanıcıların /usr/local/bin/bashHomebrew gibi bir şey kullanarak güncel bir kurulum yükledikleri OS X (Mac'ler) için geçerlidir . Arama yapan envyaklaşımı kullandığınızda, PATHkullanıcının tercihini hesaba katar ve sistemiyle birlikte gelen tercihini kullanır.


66
Basit bir soruya iyi bir cevap yazmak için zaman ayırdığınız için teşekkür ederiz.
PA

5
Ben kullanırsanız zshbenim kabuk olarak, ben kullanırım hashbang #! /usr/bin/env zsh?
stefmikhail

6
@stefmikhail: Betiği çağırmak için hangi kabuk yorumlayıcısını kullandığınız önemli değildir , betiğin içindeki#! /usr/bin/env zsh kod Z kabuğu tarafından yürütülecekse (ve yalnızca) kullanmalısınız .
Johnsyweb

1
Açıklama için +1. unutmaya eğilimliyim ama komutun anlamını bilmek hatırlamama yardımcı olacak.
Angelin Nadar

2
@Carpetsmoker Bu doğru ve hashbang ile sınırlı değil. bash betikleri her zaman UNIX satır sonlarını kullanmalıdır, aksi takdirde her komutun son argümanı, hashbang komut adında olduğu gibi ona eklenir.
lhunath

80

'Script.sh' kabuk komut dosyasını başlatmak için:

sh file.sh

bash file.sh

Başka bir seçenek, chmod komutu kullanılarak yürütülebilir izin olarak ayarlanmıştır:

chmod +x file.sh

Şimdi .sh dosyasını aşağıdaki gibi çalıştırın:

./file.sh

16

Bourne kabuğu için:

sh myscript.sh

Bash için:

bash myscript.sh

Bu oldukça açık soruyu cevapladığınız için teşekkür ederiz. Benim gibi bir Mac adamı için turlar arasındaki eski Unix komutlarını unutmak kolaydır.
PA

10

Komut dosyasının geçerli kabukta çalışmasını istiyorsanız (örneğin, dizininizi veya ortamınızı etkileyebilmesini istiyorsanız) şunları söylemelisiniz:

. /path/to/script.sh

veya

source /path/to/script.sh

Not /path/to/script.shÖrneğin, değişken olmasına . bin/script.shçalışır script.shiçinde bingeçerli dizinin altındaki dizinde.


7
İlişkili yol adlarıyla kaynak yaparken veya noktalarken çok dikkatli olun . Sen gerektiğini hep bunu yapmazsanız ./ onları başlatın ve nispi yol adı geçerli dizinde bir şey ÖNCE herhangi eğik çizgi, sen PATH şey kaynak olacak içermez! Kötüye kullanım için çok tehlikeli.
lhunath

0

İlk olarak, icra izni verin: -
chmod +x script_name

  1. Komut dosyası yürütülebilir değilse: -
    sh komut dosyasını
    sh script_name
    çalıştırmak için : - Bash komut dosyasını çalıştırmak için: -
    bash script_name
  2. Komut dosyası yürütülebilirse: -
    ./script_name

NOT : - dosyanın 'ls -a' kullanarak yürütülebilir olup olmadığını kontrol edebilirsiniz


0

.Command dosya uzantısı Terminal.app dosyasına atanır. Herhangi bir .command dosyasına çift tıklandığında dosya yürütülür.


0

Biraz ekleme, aynı klasörden bir tercüman çalıştırmak için, hala komut dosyalarında #! Hashbang kullanıyor .

Örneğin , / usr / bin dizininden kopyalanan php7.2 yürütülebilir dosyası, bir merhaba komut dosyası boyunca bir klasörde bulunur .

#!./php7.2
<?php

echo "Hello!"; 

Çalıştırmak için:

./hello

Hangisi gibi davranır:

./php7.2 hello
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.