Sto cercando di passare da bash a zsh ma preoccupato per la compatibilità degli script bash.
Tutti gli script / funzioni bash sono compatibili con zsh? Pertanto, se questo è vero, zsh è solo un miglioramento di bash?
Sto cercando di passare da bash a zsh ma preoccupato per la compatibilità degli script bash.
Tutti gli script / funzioni bash sono compatibili con zsh? Pertanto, se questo è vero, zsh è solo un miglioramento di bash?
Risposte:
Se i tuoi script iniziano con la riga #!/bin/bash
, verranno comunque eseguiti usando bash, anche se la shell predefinita è zsh.
Ho trovato la sintassi di zsh molto vicina a quella di bash e non ho prestato attenzione se c'erano davvero alcune incompatibilità. Sono passato 6 anni fa da bash a zsh senza soluzione di continuità.
.zshrc
:)
#!/bin/bash
verrà ignorata se si esegue il file di script come source ./script.sh
?
#!/usr/bin/env bash
invece usarlo , specialmente su macOS, dove il bash predefinito è gravemente obsoleto e le nuove versioni sono praticamente sempre installate in un percorso diverso.
Zsh può eseguire la maggior parte degli script Bourne, POSIX o ksh88 se lo si mette nella giusta modalità di emulazione ( emulate sh
o emulate ksh
). Non supporta tutte le funzionalità di bash o ksh93. Zsh ha la maggior parte delle funzionalità di bash, ma in molti casi con una sintassi diversa.
La shell che usi in modo interattivo è irrilevante per qualsiasi script tu abbia. La shell che esegue gli script è quella indicata nella prima riga, la riga shebang . Ad esempio, se lo script inizia con #!/bin/bash
, verrà eseguito da bash.
Se hai personalizzato bash, non sarà in grado basta rinominare il tuo .bashrc
a .zshrc
. Alcune cose possono essere condivise, ad esempio alias e funzioni, purché si mantenga l'intersezione tra le due shell (l'intersezione è vicina a ksh88 e pdksh ). Altre cose, come le impostazioni di prompt, le funzioni di completamento e la maggior parte delle opzioni, dovranno essere completamente riscritte.
Se stai scrivendo uno snippet da cui le persone provengono dalla loro .bashrc
o .zshrc
e non vuoi mantenere due versioni, segui un sottoinsieme comune di funzionalità bash e zsh, che include la maggior parte delle funzionalità di programmazione di bash. Inserisci il tuo intero codice in funzioni e metti la seguente riga nella parte superiore di ogni funzione:
if [ -n "$ZSH_VERSION" ]; then emulate -L ksh; fi
Puoi usare emulate sh
invece di emulate ksh
essere più vicino alla semplice sintassi sh, che è ciò di cui hai bisogno .profile
.
Se una funzione chiama un'altra funzione, l'altra funzione eredita l'impostazione di emulazione, quindi non è necessario inserire questa linea nelle funzioni interne, ma solo nelle funzioni chiamate dall'utente finale.
./my_script.sh
. source my_script.sh
e . my_script.sh
lo eseguirà come l'attuale shell, ignorando qualsiasi shebang.
Se lo shebang è #!/bin/bash
e si avvia lo script in quanto ./script
lo script verrà eseguito da bash. Assolutamente nessun problema qui.
Tuttavia, se lo esegui zsh ./script
o lo esegui . ./script
nell'istanza zsh in esecuzione, è abbastanza comune che la sintassi di bash e zsh non corrisponda.
Ad esempio, zsh non divide le espansioni dei parametri per impostazione predefinita, bash ha un aiuto incorporato, non c'è nessuna read -p prompt
in zsh (la sintassi è molto diversa leggi cmd \? Prompt , arrays start on 1 (not 0) in zsh,
command only search for external commands in zsh, or there is no (simple) equivalent to
$ {foo ^} `(maiuscolo solo il primo carattere) in zsh , tra gli altri. Questa è una lunga lista di (principalmente) somiglianze e alcune differenze .
In alcuni casi, si può dire a zsh di emulare altre shell. In alcuni casi, non esiste una sintassi comune portatile per entrambe le shell possibili (senza utilizzare alias o funzioni per emulare soluzioni portatili).
Tuttavia, zsh ha molte (molte) estensioni che facilitano il lavoro interattivo. Questo è allo stesso tempo un ottimo motivo per passare e un problema:
ls *(.)
(che è difficile con altre shell). Anche se guardando abbastanza in profondità la risposta diventa anche complessa in zsh ( print -rl -- *(/)
) .Con zsh:
Alla fine, è una tua scelta e mi piacciono sempre più scelte.