Yanıtlar:
Komut dosyası yalnızca işlevleri tanımlıyorsa ve başka hiçbir şey yapmıyorsa, önce source
veya .
komutunu kullanarak betiği geçerli kabuğun bağlamı içinde çalıştırabilir ve ardından işlevi çağırabilirsiniz. Daha help source
fazla bilgi için bakın .
bash
) ve exit
yalnızca alt kabuğu sonlandırır, terminalinizi değil.
Pekala, diğer cevaplar doğruyken - kesinlikle başka bir şey yapabilirsiniz: bash betiğine erişiminiz varsa, onu değiştirebilir ve basitçe "$@"
, komut satırının argümanlarına genişleyecek olan özel parametrenin sonuna yerleştirebilirsiniz. siz belirtirsiniz ve "yalnız" olduğu için kabuk onları kelimesi kelimesine çağırmaya çalışır; ve burada ilk bağımsız değişken olarak işlev adını belirtebilirsiniz. Misal:
$ cat test.sh
testA() {
echo "TEST A $1";
}
testB() {
echo "TEST B $2";
}
"$@"
$ bash test.sh
$ bash test.sh testA
TEST A
$ bash test.sh testA arg1 arg2
TEST A arg1
$ bash test.sh testB arg1 arg2
TEST B arg2
Lehçe için, önce komutun var olduğunu ve bir işlev olduğunu doğrulayabilirsiniz:
# Check if the function exists (bash specific)
if declare -f "$1" > /dev/null
then
# call arguments verbatim
"$@"
else
# Show a helpful error
echo "'$1' is not a known function name" >&2
exit 1
fi
"$@"
Çoğu durumda kullanın . $@
bazı durumlarda güvenli değildir.
bash test.sh testA testB
miyim?
[ ! -z "$1" ]
aksi takdirde kaynak bazı bash
Aşağıdaki komut önce işlevi bağlamda kaydeder, sonra çağırır:
. ./myScript.sh && function_name
Kısaca hayır.
source
( help source
Ayrıntılar için) ile komut dosyasındaki tüm işlevleri ortamınıza aktarabilirsiniz , bu da onları aramanıza olanak tanır. Bu aynı zamanda betiği çalıştırma etkisine sahiptir, bu yüzden dikkatli olun.
Bir işlevi bir kabuk komut dosyasından paylaşılan bir kitaplık gibi çağırmanın bir yolu yoktur.
kullanma case
#!/bin/bash
fun1 () {
echo "run function1"
[[ "$@" ]] && echo "options: $@"
}
fun2 () {
echo "run function2"
[[ "$@" ]] && echo "options: $@"
}
case $1 in
fun1) "$@"; exit;;
fun2) "$@"; exit;;
esac
fun1
fun2
Bu komut dosyası fun1 ve fun2 işlevlerini çalıştıracaktır, ancak onu fun1 veya fun2 seçeneğiyle başlatırsanız, yalnızca belirli bir işlevi bağımsız değişkenlerle (varsa) çalıştırır ve çıkar. kullanım
$ ./test
run function1
run function2
$ ./test fun2 a b c
run function2
options: a b c
Düzenleme: UYARI - bu her durumda işe yaramıyor gibi görünüyor, ancak birçok genel komut dosyasında iyi çalışıyor.
"Kontrol" adında bir bash betiğiniz varsa ve içinde "inşa" adında bir işleviniz varsa:
function build() {
...
}
O zaman bunu şu şekilde çağırabilirsiniz (bulunduğu dizinden):
./control build
Başka bir klasörün içindeyse, bu onu yapar:
another_folder/control build
Dosyanız "control.sh" olarak adlandırılırsa, bu da işlevi şu şekilde çağrılabilir hale getirir:
./control.sh build
. ./control.sh && build
Daha önce çalıştırılmaması gereken (örneğin tarafından source
) bash betiğinden bir işleve ihtiyaç duyduğum bir durumum var ve sorun @$
şu ki myScript.sh daha sonra iki kez çalıştırılıyor, öyle görünüyor ... işlevi sed ile çıkarmak için:
sed -n "/^func ()/,/^}/p" myScript.sh
Ve ihtiyacım olduğu anda yürütmek için bir dosyaya koyup şunu kullanıyorum source
:
sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh
aşağıdaki gibi komut satırı argümanından işlevi çağırabilirsiniz
function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1
işlev bittiğinde argümanı kabul etmek için $ 1 koyun, diyelim ki yukarıdaki kod işlevi çalıştırmak için fun.sh içine kaydedildi ./fun.sh irfan & ./fun.sh config
Çözülmüş gönderi ancak tercih ettiğim çözümden bahsetmek istiyorum. Yani, genel bir tek satırlık komut dosyası tanımlayın eval_func.sh
:
#!/bin/bash
source $1 && shift && "@a"
Ardından herhangi bir komut dosyası içindeki herhangi bir işlevi şu yolla çağırın:
./eval_func.sh <any script> <any function> <any args>...
Kabul edilen çözümle karşılaştığım bir sorun, işlev içeren komut dosyamı başka bir komut dosyası içinden kaynak alırken, ikincisinin argümanlarının birincisi tarafından değerlendirilerek bir hataya neden olmasıydı.
exit
, işlevinizde kullanırsanız , işlev çalıştırıldıktan sonra terminali kapatacak olmasıdır. Bunun etrafında herhangi bir yol var mı? @SvenMarnach