bash ihracatının zsh eşdeğeri nedir -f


24

Bu yüzden kullanmaya başladım zsh. Tamamen hoşuma gitti. Çok havalı ve kaygan görünüyor ve mevcut çalışma dizini ile gerçek komut satırının farklı satırlarda olması güzel, ama aynı zamanda , özellikle metin yazarken zshbiraz daha yavaş olabileceğini fark ediyorum bash. ekran.

En çok sevdiğim şey zsh, benim tanımladığım tüm işlevlerle 'geriye uyumlu' idi .bashrc.

Biri olsa yakın. İşlevlerin tümü mükemmel çalışıyor ancak dışa aktarma sisteminin nasıl çalıştığını çözemiyorum.

Bu .bashrcişlevlerden bazılarını dışa aktardım, böylece onları komut dosyalarında ve dış programlarda olduğu gibi başka yerlerde de kullanabilirdim export -f.

Zsh'de, ihracattan bahsedilmiş gibi görünmüyor bile. Otomatik yükleme mi? Bu iki şey aynı mı? Bunu anlamak için çok zor zamanlar geçiriyorum.


2
Bu çok eski bir sorudur, ancak "geçerli çalışma dizini ve gerçek komut satırı farklı satırlardadır" ifadesinin zsh ile ilgisi olmadığını söylemek istiyorum. İsteğinizi nasıl ayarladığınıza bağlı, hepsi bu.
4ae1e1

Yanıtlar:


11

İşlevleri içeren ortam değişkenleri bir bash hack. Zsh'da benzer bir şey yok. Birkaç kod satırına benzer bir şey yapabilirsiniz. Ortam değişkenleri karakter dizileri içerir; bash'ın eski sürümleri, Shellshock keşfedilmeden önce , fonksiyonun kodunu, adı fonksiyonun adı olan ve () {ardından fonksiyonun kodunu takip eden bir değişkende sakladı} . Bu kodlamaya sahip değişkenleri içe aktarmak için aşağıdaki kodu kullanabilir ve bunları bash benzeri ayarlarla çalıştırmayı deneyebilirsiniz. Zsh'nin tüm bash özelliklerini taklit edemediğini unutmayın, yapabileceğiniz tek şey biraz daha yaklaşmaktır (örneğin $foo, değeri bölmek ve joker karakterleri genişletmek ve dizileri 0 tabanlı yapmak).

bash_function_preamble='
    emulate -LR ksh
'
for name in ${(k)parameters}; do
  [[ "-$parameters[name]-" = *-export-* ]] || continue
  [[ ${(P)name} = '() {'*'}' ]] || continue
  ((! $+builtins[$name])) || continue
  functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done

( Shellshock'un orijinal keşfi Stéphane Chazelas'ın belirttiği gibi, bu cevabın daha önceki bir sürümü, eğer fonksiyon tanımı yanlış biçimlendirilmişse, bu noktada isteğe bağlı kod çalıştırabilirdi. çevreden ithal edilen bir işlev olabilir.)

Bash kodlamasının Shellshock sonrası sürümleri, ortamdaki geçersiz değişken adlarını (örn. BASH_FUNC_myfunc%%) Kullanır . Bu, zsh, bu tür değişken isimlerini ortamdan çıkarmak için bir arayüz sağlamadığından güvenilir şekilde ayrıştırmalarını zorlaştırır.

Bunu yapmanı tavsiye etmiyorum. Dışa aktarılan işlevlere komut dosyalarına güvenmek kötü bir fikirdir: komut dosyanızda görünmez bir bağımlılık oluşturur. Komut dosyanızı, işleve sahip olmayan bir ortamda (başka bir makinede, bir cron işinde, kabuk başlatma dosyalarınızı değiştirdikten sonra…) çalıştırırsanız, komut dosyanız artık çalışmaz. Bunun yerine, tüm işlevlerinizi bir veya daha fazla ayrı dosyada (bunun gibi bir şey ~/lib/shell/foo.sh) saklayın ve kullandığı işlevleri ( . ~/lib/shell/foo.sh) alarak komut dosyalarınızı başlatın . Bu şekilde, değiştirirseniz foo.sh, hangi komut dosyalarının buna dayandığını kolayca arayabilirsiniz. Bir komut dosyasını kopyalarsanız, hangi yardımcı dosyalara ihtiyaç duyduğunu kolayca bulabilirsiniz.

Zsh (ve ondan önceki ksh), işlevleri kullanılan komut dosyalarına otomatik olarak yüklemek için bir yol sağlayarak bunu daha uygun hale getirir. Kısıt, dosya başına yalnızca bir işlev koyabileceğinizdir. Fonksiyonu otomatik olarak yükler ve fonksiyon tanımını, fonksiyonun adı olan bir dosyaya koyun. Bu dosyayı $fpath( FPATHortam değişkeni ile yapılandırabileceğiniz) içinde listelenen bir dizine yerleştirin . Komut dosyanızda, autoloaded işlevleri ile ilan edin autoload -U foo.

Ayrıca, zsh ayrıştırma zamanından tasarruf etmek için komut dosyalarını derleyebilir. zcompileBir betiği derlemek için arayın . Bu .zwcuzantılı bir dosya oluşturur . Bu dosya varsa autoload, kaynak kod yerine derlenmiş dosyayı yükler. Sen kullanabilirsiniz zrecompileişlevini Bir dizindeki için (yeniden) derleme tüm işlev tanımları.


1
Kodunuzun, aynı kabuk deposu güvenlik açığı ile aynı şekilde olması komik bash(değişken değişken içeriğinin yalnızca bir işlev tanımı olduğunu ve HTTP_HOSTveya gibi herhangi bir değişken adını işlediğini doğrulamaz LC_X). Aksi takdirde iyi cevap.
Stéphane Chazelas

@ StéphaneChazelas Ortamdan içe aktarılan işlevlerle komutları çalıştıracaksanız, hemen hemen kaybettiniz. Ancak alma kodunu rastgele kod çalıştırmayacak şekilde güncelleştirdim. Ancak çok kullanışlı değildir, çünkü post-shell şoku bash, dışa aktarılan fonksiyonlarını aynı şekilde kodlamaz.
Gilles 'SO- kötülük' stop

Şimdi CVE-2014-6271'in eşdeğerini düzelttiniz, ancak hala zsh ayrıştırıcısını herhangi bir değişkende kodlamaya maruz bırakmaya devam ettiğiniz için muhtemelen CVE-2014-6277 / 6278 türündeki birçok güvenlik açığına maruz kalıyorsunuz (kod gibi bazı bağlamlarda saldırganların kontrolünde potansiyel olduğunu, bazı dahil zsh -c 'functions[f]=$VAR' edilir ayrıştırılır bile fişlevi hiçbir zaman çağrılmaz). Çözüm, yalnızca isminin kendisi gibi ayrılmış bir şablonu izleyen değişkenleri göz önünde bulundurmaktır $BASH_FUNC_x%%, ancak sizin de dediğiniz gibi bunları zshlistelemek veya almak için API yoktur. perlÖrneğin aramanız gerekir .
Stéphane Chazelas

7

İşlev bildiriminizi .zshenv dosyasına koyarsanız , işleviniz herhangi bir çaba göstermeden bir komut dosyasından kullanılabilir.


Neden cevabımı düşürdün? Lütfen açıkla.
rools

Hala bir cevap bekliyorum ve hala çalışıyor!
rools

Bu cevabı yeni keşfettim ve bu ideal bir çözüm.
AFH

Oy vermedim. OP, TBH .bashrc'dan bir şeyler ihraç etmek istiyordu, ki bu kötü bir fikir, bir betiğe koymak daha iyi, böylece çok büyük bir ortama sahip olmuyorsunuz. Ancak çözümünüz aynı kötü fikrin bir değişkenidir, tüm komut dosyalarınızı koyun .zshenvve hiç kullanılmayan çok fazla kodu ayrıştırarak zsh'nin her türlü çağrısını yavaşlatır. Ayrıca, bir işlevi dışa aktarma işlevi ile aynı değildir, dışa aktarılan bir değişken gibi, dışa aktarılan bir işlev yalnızca alt işlemler için kullanılabilir. Oysa koyduğunuz şeyler .zshenvher zsh tarafından kullanılabilir.
Metamorfik

Son olarak, koyduğunuz kişisel koda güveniyorsanız, .zshenvtüm komut dosyalarınız tamamen taşınabilir olmayacaktır. Normalde komut dosyaları birbirine bağlı olabilir, bu iyi, onları birlikte dağıtabilirsiniz. Ancak, özel işlevlere sahip olmalarına bağlı olarak .zshenv, hiç kimse bunları kullanmak istemeyecek veya ZDOTDIRkendi işinizin yapılmasını önleyen, özel bir şekilde çağrılması gerekecek .zshenv. Bu bir acı olurdu.
Metamorfik
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.