Aşağıdakileri denedim ama işe yaramıyor gibi görünüyor:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
Aşağıdakileri denedim ama işe yaramıyor gibi görünüyor:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
Yanıtlar:
Bunun işe yaramamasının nedeni -i /bin/sh
, tek bir argüman olarak görmesidir env
. Genellikle bu 2 argüman olur -i
ve /bin/sh
. Bu sadece mesele sınırlamasıdır. Kaçış yok.
Ancak bu görevi hala farklı bir yolla gerçekleştirebilirsiniz.
Bu görevin komut dosyasının kendisi tarafından gerçekleştirilmesini istiyorsanız ve bunun gibi bir şey env -i script.sh
yapmanız gerekmiyorsa, komut dosyasının kendisini yeniden çalıştırmasını sağlayabilirsiniz.
#!/bin/sh
[ -z "$CLEANED" ] && exec /bin/env -i CLEANED=1 /bin/sh "$0" "$@"
Bu, CLEANED
ortam değişkeni ayarlanmamışsa komut dosyasının kendini yeniden yürütmesine neden olur . Sonra yeniden yürütme, bir döngüye girmemesini sağlamak için değişkeni ayarlar.
env
GNU coreutils'in artık buna -S
benzer ancak tam olarak aynı olmayan sorunları çözme seçeneği var . Örneğin #!/usr/bin/env -S perl -T
.
#!/usr/bin/env -S -i /bin/sh
. Taşınabilirlik sorunlarının farkında olun.
Komut dosyanızı şununla çalıştırın env -i
:
env -i script.sh
Ve senaryo her zamanki gibi:
#!/bin/sh
# ... your code here
Temiz bir ortamla koşmak istiyorsan, açıkça çalıştırdığın zaman. Eduardo Ivanec bu cevapta bazı fikirler veriyor exec
, ortam temiz olmadığında betiğinizi yinelemeli olarak çağırabilirsiniz (örn. $ HOME tanımlanır):
[ "$HOME" != "" ] && exec -c $0
Bash ile şu şekilde yapabilirsiniz:
#!/usr/bin/bash
set -e
set -u
[ -v HOME ] && exec -c "$0" "$@"
# continue with the rest of the script
# e.g. print the cleaned environment:
export
set -e
Ve set -u
komutlar kesinlikle gerekli değildir, ancak ben onları bu yaklaşım (örneğin olarak tanımsız değişkenler erişen dayanmaz olduğunu göstermek için dahil [ "$HOME" != "" ]
olur) ve uyumlu set -e
bir ortamda.
HOME
Değişkenin test edilmesi güvenli olmalıdır, çünkü bash komut dosyalarını etkileşimli olmayan modda yürütür, yani ~/.bashrc
başlatma sırasında (ortam değişkenlerinin ayarlanabileceği) gibi yapılandırma dosyaları kaynaklanmaz.
Örnek çıktı:
declare -x OLDPWD
declare -x PWD="/home/juser"
declare -x SHLVL="1"
Linux 2 argümanlı sapma sınırlaması (yorumlayıcı + tek argüman) çoğu cevapta belirtilmiştir, ancak bunun yapılamayacağını söylemek yanlıştır - tek bir argümanla yararlı bir şey yapabilen bir tercümana geçmeniz gerekir:
#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here
Bunun yaptığı, bağımsız değişkenleri doğru bir şekilde tırnak içine alan (daha ucuz ) ve çağıran perl
tek satırlı bir script ( -e
) ile çağırmaktır . Gerekirse daha fazla mantık eklenebilir ( karakterlerle sınırlı olduğunuz için Linux'ta çok fazla olmasa da, muhtemelen 128)%ENV
env -i
exec /bin/sh
perl
BINPRM_BUF_SIZE
Ne yazık ki, bu Linux'a özgüdür, çoklu shebang argümanlarına izin veren bir sistemde çalışmaz: - /
perl
o oluyor böylece, tek bir argüman olarak bu dizeyi işler alıntı değil normalde ile yapacağı gibi yukarıdaki perl -e ...
bu korunur tırnak eklemeniz durumunda (komut satırından, perl bir işe yaramaz şikayet edecek Üzerinde uyarılarıyla, sadece bir hazır dize görür sabit).
Ayrıca, bu şekilde kullanıldığında davranışta küçük bir değişiklik olduğunu, @ARGV
normalde sadece argümanları $0
içerdiğini ve komut dosyasını içerdiğini unutmayın, ancak bu shebang $ARGV[0]
ile komut dosyasının adı (ve $0
is -e
) biraz daha kolaylaşır.
Bunu -c
, eski AT&T'nin komut satırını (ekstra bir argüman olmadan ) "yeniden işleyen" bir tercümanla da çözebilirsiniz ksh93
:
#!/bin/ksh /usr/bin/env -i /bin/sh
ama belki de ksh
günümüzde yaygın değil ;-)
( bash
ile benzer bir özelliğe sahiptir --wordexp
, ancak çalıştığı sürümlerde "belgesizdir" ve belgelendiği sürümlerde derleme zamanında etkinleştirilmez: - / İki bağımsız değişkene ihtiyaç duyduğundan bunun için de kullanılamaz. ..)
Ayrıca, @Patrick ve @ maxschlepzig'in cevaplarında etkili bir varyasyon:
#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here
Aksine yeni değişken kullanımı daha bu kullanımları özel " _
bash" tam olarak ayarlı değilse değişken "" daha sonra senaryoyu değiştirmek exec
kullanarak -a
yapmak için ARGV[0]
(ve dolayısıyla $_
"Bash ve kullanarak) sadece" -c
çevreyi temizlemek için.
Alternatif olarak, betiğin başında ortamı temizlemek kabul edilebilirse (yalnızca bash):
#!/bin/sh
unset $(compgen -e)
# your script here
Bu compgen
, dışa aktarılan tüm ortam değişkenlerinin adlarını listelemek ve unset
bunları tek seferde kullanmak için (tamamlama yardımcısı) kullanır .
Ayrıca , shebang davranışının genel sorunu hakkında daha fazla bilgi için shebang'daki çoklu argümanlar bölümüne bakınız .