OpenCode i nepopunjen PATH: Zašto vaši alati nisu bili u shellu agenta
Објављено 21 April 2026
- Scena: slep agent u svetu alata
- Anatomija greške: dva shella, dva sveta
- Krivci: .zshrc vs .zshenv
- Korak po korak dijagnostika
- Решение : .zshenv + правине путање
- Slucaj NVM: kada menadžer verzija zaboravi da ostavi trag
- pregledna tabela putova
- Peštere i mitigations
- Научене лекcije
- Finalna proverka
- Linkovi
Pokrećete OpenCode u svom terminalu, sve radi. Agent pokušava`gh`— nepronađen. Jedan`java -version`— nedostaje. Jedan`node`— нигде. Ме intermediary, ови алатови су добро там у ваше шеллу. Проблем? OpenCode покреће шелове.ne-interaktivnikoji nikada ne čitaju vaš`.zshrc`. Ово је како да дијагностикујете и исправите то на правилан начин.
- tak
-
[]
Scena: slep agent u svetu alata
Bio je utorak večer. Pres sam instaliraohttps://opencode.ai[OpenCode], AI agent koji je obećao da će promeniti moj način kodiranja. Prvi test: zamoliti ga da izlistati moje GitHub repozitorijume.
$ opencode
> Utilise gh pour lister mes repos
❌ bash: gh: command not found
Čudno.gh fonctionnait parfaitement dans mon terminal. J’essaie autre chose :
> Vérifie la version de Java
❌ bash: java: command not found
Затим:
> Lance le build Gradle
❌ bash: gradle: command not found
Java, Gradle, Node,gh— Sve je bilo nevidljivo agentu. Moj terminal, on, je vidio sve. Kao da je agent i ja živeli u dvama paralelnim svetima.
Potrošio sam sate da razumem. Sati`echo $PATH`, de which java, od rastuće frustracije. Konačno sam razumeo da problem nije u alati — bilo jeлушпа. OpenCode, kao svaki agent koji pokreće podprocesse, radi u shell-ovimaneinteraktivni. I Zsh, u ovim shell-ovima, jednostavno ignoriše vaše`.zshrc`.
Sledeći je potpuni izveštaj o ovom dijagnozu, o ovom rešenju i o ovoj lekciji koju sam naučila. Ako koristite AI agent — OpenCode, Aider, Cursor, ili čak i cron skripte — ovaj problem će vas jednog dana tići.
Anatomija greške: dva shella, dva sveta
Kada otvarate terminal, Zsh ga traktira kao shellинтерактиван. Он заређује`.zshrc`, koji inicijalizuje sve : SDKMAN, NVM, pnpm, alias, vaš leп prompt. Vaše okruženje je kompletno.
Но када OpenCode изврши команду, не покреће интерактивни терминал. Он покреће шелу.neinteraktivni— shell zadatka, bez čoveka iza ekrana. I Zsh, u ovom kontekstu, skače`.zshrc`. On samo čita`.zshenv`.
Zasto postoji ova razlika? Jer neinteraktivni shell je namenjen izvršavanju skriptova, a ne služenju ljudskog korisnika. Učitavanje aliasa, prompta i završetaka u skriptu koja radi u pozadini bila bi istrata. Problem jeste što vaš PATH — najvažnija informacija za pronalaženje izvršnih fajlova — se često inicijalizuje u`.zshrc`, nije u`.zshenv`.
@startuml skinparam backgroundColor #FEFEFE actor "Ви" as user actor "OpenCode\n(agent)" as agent participant "Shell interaktivno (.zshrc učitan)" as ishell participant "Shell\nneinteraktivni\n(.zshrc je ignorisan)" as nshell user -> ishell : gh, java, node ✅ agent -> nshell : gh, java, node ❌ note right of ishell Source .zshrc : - SDKMAN init - NVM init - ~/apps dans PATH - pnpm dans PATH end note note right of nshell .zshrc ignoré ! PATH = /usr/bin:/bin + quelques répertoires défaut end note @enduml
Koren problema:Zsh izvršava .zshrc samo za interaktivne shellove. OpenCode, kao i svaki AI agent koji pokreće podprocesse, koristi neinteraktivne shell-ove. Ovi shell-ovi ne čitaju`.zshenv`.
Krivci: .zshrc vs .zshenv
Zsh imaчетири фајла иницијализације, svaki sa specifičnom ulogom. To je elegantan dizajn — ali to je i čvor problema :
Fajl |
изворен када |
Улога |
Modifikuj PATH? |
|
Uvek(interaktivan + neinteraktivan + login) |
Неопходне променљиве околине, PATH |
✅ Да — то је SA mjesto |
|
Само шељеве за логин |
Sporе komande (jednom po sesiji) |
Moguće |
|
Само интерактивне лиуске |
Alias, prompt, dovršavanje, interaktivni alati |
❌ Nije za kritične promenljive |
|
Shell-ovi za prijavu (posle .zshrc) |
Поруке добро дошлица, завршетак |
Ретако |
Tabela daje pokazatelj, ali ga je potrebno duboko razumeti. Mislite na to kao na sobe kuće:
-
`.zshenv`jeulazni hol— svi prođu tamo, posetilac ili stanovnik. Ako stavite nešto ovde, svaki shell će moći da ga vidi.
-
`.zshrc`јеsalon— sami stanovnici (interaktivne ljuške) ulaze tamo. Posetioaci (neinteraktivne ljuške) ostaju u holu.
-
.zprofileet `.zlogin`Su specijalizovani delovi za login shellove (kao kada se povežete pomoću SSH).
Tragediya je da većina od nas stavimo PATH u dnevnu sobu. A AI agent, on, nikada nema pravo da uđe tamo.
Problem u dijagramu :
@startuml
skinparam backgroundColor #FEFEFE
start
if (Shell interactif ?) then (Oui)
:Source .zshenv;
:Source .zprofile;
:Source .zshrc;
:Source .zlogin;
note right
SDKMAN ✅
NVM ✅
~/apps ✅
pnpm ✅
end note
else (Non — shell non-interactif)
:Source .zshenv uniquement;
note right
SDKMAN ❌
NVM ❌
~/apps ❌
pnpm ❌
end note
endif
stop
@enduml
Kada otvarate terminal, Zsh je interaktivan: čita`.zshrc`, sve radi. Kada OpenCode pokreće shell da izvrši komandu, Zsh je neinteraktivan : on preskače`.zshrc`, сам чита`.zshenv`. Et si `.zshenv`ne postoji ili ne sadrži PATH — to je pustinja.
|
Zasto Zsh to radi?Ovo je izbor dizajna nasleđen od Unix-a. Neinteraktivni shell mora bitibrz et репродуктиванUčitavanje aliasa, obojenih promptova i teških inicijalizacija SDKMAN-a u cron skriptu ili agente AI bi bilo sporo i křehko. Odvajanje je zato logično:`.zshenv`glavno (varijable, PATH)`.zshrc`za komfor (alias, prompt, kompletujemo). Problem se javlja kada stavimo najvažnije u komfor. |
Korak po korak dijagnostika
Pre nego što ispravite, morate da razumete tačno šta nedostaje. Ovo je ponovljiva dijagnostička metoda — sačuvajte je u omiljenim ako radite sa AI agensima.
Проверити PATH агента
Poredimo ono što vidi vaš interaktivni terminal sa onim što vidi neinteraktivna shell — to jest, ono što vidi OpenCode.
# Dans votre terminal interactif (tout fonctionne)
echo $PATH | tr ':' '\n' | grep -v '^/usr' | sort
Tipičan rezultat :
/home/cheroliv/apps
/home/cheroliv/.nvm/versions/node/v22.19.0/bin
/home/cheroliv/.sdkman/candidates/java/current/bin
/home/cheroliv/.sdkman/candidates/gradle/current/bin
/home/cheroliv/.local/share/pnpm
/home/cheroliv/.local/bin
Sada, simulirajmo šta agent vidi — neinteraktivna lupina:
# Shell non-interactif : pas de .zshrc
zsh -c 'echo $PATH' | tr ':' '\n' | grep -v '^/usr' | sort
Резултат :
/home/cheroliv/.local/bin
Pet od šest puteva je nestalo.Agent je amputovan na 83% svog okruženja. Kao da se vam pita da kuhate bez pola vaših posuđa — mogli biste provriti vodu, ali i baš malo više.
|
Naredba`zsh -c 'echo $PATH'`је вашalat dijagnostike broj 1. Ако алат који користите свакодневно није приступан у резултату, ваш ИА агент такође неће моћи да га види. Тестирајте ње пре и након сваке измене`.zshenv`. |
2. Identifikati šta se nalazi u .zshrc, ali ne u .zshenv
Sada, tražimo krivca u`.zshrc`. Filtriramo redove koji spominju naša alat:
grep -n 'apps\|SDKMAN\|NVM\|PNPM\|PATH' ~/.zshrc
Tipično se nađe:
119: PATH="/usr/bin/python3:$HOME/apps:$PATH" # ← pas exporté !
171: export NVM_DIR="$HOME/.nvm"
172: [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # ← NVM init
176: nvm use --lts --silent # ← active une version
179: export PNPM_HOME="/home/cheroliv/.local/share/pnpm"
187: export SDKMAN_DIR="$HOME/.sdkman"
188: [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh"
Sve to jeневидимза OpenCode. И он`PATH`linije 119 nije ni`export`é — On nikada ne napušta trenutni shell. To je ključan tehnički detalj: varijabla bez`export`ostaje lokalno za shell koji ga definiše. Pod-šelovi — kao oni pokrenuti od strane OpenCode — ga nikad ne nasleđuje.
3. Проверити да ли .zshenv постоји
cat ~/.zshenv 2>/dev/null || echo "FICHIER ABSENT"
Ako je odgovor « FICHIER ABSENT », tu se sve odigrava.
Решение : .zshenv + правине путање
Strategija je jednostavna, ali zahteva preciznost: staviti u`.zshenv` самоosnovne putevi, bez učitavanja tehkih skriptova inicijalizacije. Ne pomeramo`.zshrc`у`.zshenv`— izvučemo suštinu.
Kreirati .zshenv sa svim neophodnim putanjama
`.zshenv`јеjedan fajlда Zsh гарантује да се извори уsviконтексти. Тамо треба да иде PATH.
export SDKMAN_DIR="$HOME/.sdkman"
export NVM_DIR="$HOME/.nvm"
export PNPM_HOME="$HOME/.local/share/pnpm"
export PATH="$HOME/apps:$HOME/.sdkman/candidates/java/current/bin:$HOME/.sdkman/candidates/gradle/current/bin:$HOME/.nvm/current/bin:$PNPM_HOME:$HOME/.local/bin:$HOME/.local/share/JetBrains/Toolbox/scripts:/usr/bin/python3:$PATH"
|
Korišćeno je`$HOME/.nvm/current/bin`i ne`$HOME/.nvm/versions/node/v22.19.0/bin`. Razlog: verzije Node se menjaju. Tvrdokodirana putanja postaje netačna u sledećem. |
Zašto ne source sdkman-init.sh u .zshenv?
Najprivlačniji pristup bi bio da se jednostavno reproducira u`.zshenv`šta radimo u`.zshrc`— izvršiti skripte inicijalizacije. Onmogao bibiti pokušen da uradi :
# ❌ MAUVAISE IDÉE
[[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh"
Проблеми :
-
sporan:`sdkman-init.sh`Pravi mrežne resolucije i proverke na svakom shell-u. U neinteraktivnom shell-u, to je nepotrebni trošak.
-
fragilan: SDKMAN očekuje interaktivni kontekst. Njegova inicijalizacija može tiho neuspeti u cevi ili pod-šeliju.
-
Bezvažno: SDKMAN postavlja svoje kandidate u`~/.sdkman/candidates/<tool>/current/bin`— stabilni simbolički linkovi koji pokazuju na aktivnu verziju. Možemo ih koristitidirektno.
Дobar приступ: облазити иницијалисање на SDKMAN и право показује на симлинкове`current`. Ово је кључ свега решења :koristiti strukturu fajlova kao ugovor, umesto koda inicijalizacije.
@startuml
skinparam backgroundColor #FEFEFE
rectangle "Spor pristup
(source sdkman-init.sh)" as slow {
card ".zshenv source sdkman-init.sh
2-3 sekunde po shellu
Mrežne proverke
Rizik neuspeha" as s1 #FDEDEC
}
rectangle "Brzi pristup
(direktni simbolički linkovi)" as fast {
card ".zshenv export PATH=...current/bin
0 ms
Nema mreže
Nema inicijalizacije" as s2 #E8F8E8
}
slow --> fast : Même résultat final\nLe PATH pointe sur current/bin\ndans les deux cas
@enduml
Slucaj NVM: kada menadžer verzija zaboravi da ostavi trag
проблем NVM
Ovdje me je istraživanje doveo najdaleko. SDKMAN ima elegantan dizajn: kada uradimo`sdk install java 25.0.2-tem`, On pravi simbollink :
~/.sdkman/candidates/java/current -> ~/.sdkman/candidates/java/25.0.2-tem
Ovaj symlink jeувек ажурирано. Ukažite na njega u`.zshenv`Јсте зашћени, без обзира на шелл. Прелепо.
Nikad, on ne kreiraништаod tel. Nema symlink`current`. Nema stalne tacke sidra. Moramo pokazivati na ugrađen (ukočen u kod) verzionisan put, koji izgleda ovako :
~/.nvm/versions/node/v22.19.0/bin/node
Na sledeći`nvm install 24`, Ovaj put je mrtav. Vaš`.zshenv`Pokazivač na verziju koja više nije aktivna verzija. Ovo je vremenska bomba.
|
Zašto NVM to radi?NVM radi dinamičkim modifikovanjem PATHa pri svakom`nvm use`. Namenjen je za developere koji često menjaju verziju, u interaktivnom shellu. Simbolička veza`current`Nije bio u početnim specifikacijama — ovo je greška u dizajnu koju ćemo sami ispraviti. |
@startuml
skinparam backgroundColor #FEFEFE
package "SDKMAN ✅" {
[~/.sdkman/candidates/java/current] as sdk_current
[~/.sdkman/candidates/java/25.0.2-tem/] as java_25
[~/.sdkman/candidates/java/21.0.7-tem/] as java_21
sdk_current --> java_25 : symlink
}
package "NVM ❌ (pre korekcije)" as nvm_before {
[~/.nvm/versions/node/v22.19.0/] as node_22
[~/.nvm/versions/node/v20.16.0/] as node_20
note right of node_22
Pas de symlink current !
.zshenv doit pointer en dur
Cassé au prochain nvm install
end note
}
package "NVM ✅ (nakon korekcije)" as nvm_after {
[~/.nvm/current] as nvm_current
[~/.nvm/versions/node/v22.19.0/] as node_22b
[~/.nvm/versions/node/v20.16.0/] as node_20b
nvm_current --> node_22b : symlink\n(mis à jour auto)
}
@enduml
Rešenje: napraviti simbolički link current za NVM
Posto NVM ne radi to, mi to radimo sami. Princip je isto kao SDKMAN — jedan symlink.`current`Kreiramo ga jednom, zatim ga automatizujemo da se ažurira sam.
# Créer le symlink initial
ln -sfn "$HOME/.nvm/versions/node/v22.19.0" "$HOME/.nvm/current"
Sada, u`.zshenv`, koristi se :
$HOME/.nvm/current/bin
Umesto :
# ❌ Chemin en dur — cassé au prochain changement de version
$HOME/.nvm/versions/node/v22.19.0/bin
Automatizuj ažuriranje symlinka
Симлинк није вредан ако се не ажурира. Симлинк`current`Treba da se ażurira kada se radi`nvm use` ou nvm install. Решење: једанomotač— funkcija koja omotava stvarnu komandu`nvm`i ažurira simboličku vezu nakon svakog poziva.
# À la fin de .zshrc, APRÈS le chargement de NVM
nvm use --lts --silent
ln -sfn "$(nvm_version_path "$(nvm current)")" "$NVM_DIR/current"
_nvm() {
command nvm "$@"
local rc=$?
ln -sfn "$(nvm_version_path "$(nvm current)")" "$NVM_DIR/current"
return $rc
}
alias nvm='_nvm'
Kako to funkcionise, u detalju :
@startuml skinparam backgroundColor #FEFEFE actor Développeur participant "nvm wrapper\n(_nvm)" as wrapper participant "nvm реальан (команда nvm)" as realnvm participant "~/.nvm/current\n(simbolički link)" as symlink Développeur -> wrapper : nvm use 20 wrapper -> realnvm : command nvm use 20 realnvm --> wrapper : version activée wrapper -> symlink : ln -sfn .../v20.16.0 ~/.nvm/current wrapper --> Développeur : retour note right of symlink Toujours à jour ! Utilisé par .zshenv → accessible par OpenCode end note @enduml
Omotač`_nvm`zove pravi komanda`nvm`, zatim ažurira simlink. Alias`nvm='_nvm'`osigurava da prilikom unosa`nvm`, prolazimo kroz omotač. I pri inicijalizaciji shella, ponavljamo isto posle`nvm use --lts`.
|
`nvm_version_path`Ово је унутрашња функција NVM-а која решава комплетан пут до конкретне верзије. Ово спречава ручно постављање пута. |
pregledna tabela putova
Пре него што пређеш на застане, визуелни сажетак трансформације. На левој страни, што ste imали (сав у`.zshrc`, nevidljivo za agenta). Desno, što sada imate (osnovni putevi u`.zshenv`, vidljivi svuda).
| alat | Pre (.zshrc samo) | После (.zshenv + simblična veza) | Vidljiv od OpenCode? |
|---|---|---|---|
|
PATH nije izvozen u .zshrc |
`$HOME/apps`у .zshenv |
✅ |
SDKMAN Java |
`sdkman-init.sh`izvorljeno u .zshrc |
`$HOME/.sdkman/candidates/java/current/bin`у .zshenv |
✅ |
SDKMAN Gradle |
`sdkman-init.sh`uvođen u .zshrc |
`$HOME/.sdkman/candidates/gradle/current/bin`u .zshenv |
✅ |
NVM čvor |
`nvm use --lts`у .zshrc |
`$HOME/.nvm/current/bin`u .zshenv (simbolička veza) |
(No output, as there is no French text provided to translate) |
pnpm |
`$PNPM_HOME`у .zshrc |
`$PNPM_HOME`у .zshenv |
✅ |
JetBrains Toolbox |
Automatski dodat od Toolbox u `.zshrc |
`$HOME/.local/share/JetBrains/Toolbox/scripts`у .zshenv |
✅ |
Python 3 |
`/usr/bin/python3`у PATH .zshrc |
Izričito u .zshenv |
✅ |
Peštere i mitigations
Nije sve savršeno sa ovim pristupom. Evo problema koje sam naišao, i kako ih obistći.
| уловка | Opis | umerenje |
|---|---|---|
PATH duplikovan |
Ako .zshenv i .zshrc dodaju istu putanju, pojavljuje se dva puta |
`.zshenv`je izvornoпре.zshrc. Oba se čitaju u interaktivnoj ljusci. PATH se može duplirati. To je kosmetičko, ne funkcionalno. Da se izbegne: stavite u .zshenv samo putanje koje nisu prisutne u podrazumevanom PATH-u. |
NVM : hardkodirana verzija u .zshenv |
staviti`~/.nvm/versions/node/v22.19.0/bin`тврд постаје нетачан у следећем`nvm install` |
Користити симлинк`$HOME/.nvm/current/bin`+ омотач`_nvm`у .zshrc |
SDKMAN : izvršavanje sdkman-init.sh u .zshenv |
Spor, ranljiv, bez korisnosti u neinteraktivnoj ljusci |
Користите симлинкове`candidates/<tool>/current/bin`direktno |
Nedostajući alias nakon izmene |
Omot`nvm='_nvm'`у .zshrc утиче само после релоадовања |
Покрени shell ponovno hoặc`source ~/.zshrc` |
OpenCode ne vidi promene |
Agent je već pokrenuo svoje potkornice sa starim .zshenv |
Рестартуј OpenCode после измене .zshenv |
.zshenv преоптерећен |
Stavljati teške funkcije ili interaktivne inicijalizacije u `.zshenv |
.zshenv = promenljive okruženja + PATH samo. Nema`source`, bez teških funkcija, bez promptova. |
Научене лекcije
-
.zshrc` je interaktivan,
.zshenvje univerzalni— Ako jedna promenljiva mora da postoji u svim shell-ovima (agenti IA, cron, skripte, IDE), ona ide u`.zshenv`. Salon je udoban, ali ulazni hol je jedino mesto gde prolazi sve. -
Menadžeri verzija nisu jednaki— SDKMAN kreira simbolne veze`current`po dizajnu. NVM ne. Treba ručno popuniti ovaj nedostatak. Ovo je važna lekcija: pre podešavanja vašeg PATH, proverite da li vaš menadžer nudi stabilnu kotvicu.
-
Ne učitati init skripte u .zshenv—
sdkman-init.shet `nvm.sh`Su dizajnirani za interaktivni shell. Oni su spori i krehki u neinteraktivnom kontekstu. Simbolički linkovi`current`Oni su dovoljni i instantani. -
Uvek testirati u neinteraktivnom shell-u—`zsh -c 'echo $PATH'`tačno simulira šta vidi agent. To je test validacije. Bez ovog testa, ne znate da li vaša konfiguracija funkcionise za agente.
-
Wrapper pattern je ponovo upotrebljiv— Isti pattern`_nvm`+`alias nvm='_nvm'`Primena se na sve alate koji dinamički menjaju PATH bez ostavljanja stabilnog traga. Ovo je još jedan alat u vašoj kutiji ideja.
@startuml
skinparam backgroundColor #FEFEFE
rectangle "prije" as avant {
card "Shell interaktivni : ✅
Shell neinteraktivni : ❌
OpenCode : ❌
Cron : ❌
Skripte : ❌" as av1 #FDEDEC
}
rectangle "nakon" as apres {
card "Interaktivni shell : ✅\nNeinteraktivni shell : ✅\nOpenCode : ✅\nCron : ✅\nSkripte : ✅" as ap1 #E8F8E8
}
avant --> apres : .zshenv +\nsymlink ~/.nvm/current
@enduml
Finalna proverka
Posle kreiranja`.zshenv`et symlink NVM, проверијте да све функционише — у два контекста :
# Shell interactif (votre terminal)
gh --version && java -version && node --version
# Shell non-interactif (simulation OpenCode)
zsh -c 'gh --version && java -version && node --version'
Oba moraju da uspeju. Ako da, vaš agent AI će videti isti alat kao vi. Ako ne, vratite se na korak po korak dijagnozu — verovatno ste zaboravili putanju ili NVM symlink nije ažuriran.
|
Automate ovaj test.Dodajte ovu proveru u skriptu healthcheck koju pokrećete nakon svakog ažuriranja vaših alata.`zsh -c 'which java && which node && which gh'`u CI, to je osiguranje protiv iznenađenja. |
Čuvajte sve blokove koda u backtick-ovima (…) istačno — nikad ne menjajte sadržaj backtick-ova, razmake ili poziciju. Ovaj tekst može biti fragment većeg rečenice — prevedite fragment bez zahtevanja dodatnog konteksta. Izlazite samo prevedeni tekst — bez objašnjenja, komentarata, uvoda, alternativa ili opcija. Neinteraktivan shell je kao tiho gost: on čita samo ono što je prikazano na ulaznoj vrati. Ako je PATH u salašnom prostoru, on ga nikad neće videti. __
Linkovi
Službena dokumentacija
-
Dokumentacija Zsh : Pokretne datoteke— Službena referenca za datoteke za inicijalizaciju Zsh. Ovo je mesto gde se sve objašnjava, iako se često zaboravlja.
-
OpenCode : konfiguracija— Kako podesiti OpenCode i njegovo okruženje izvršavanja.
Navedeni alati
-
NVM na GitHub— Node Version Manager. Upravnik verzija Node.js.
-
SDKMAN — zvanični sajt— SDKMAN! Menadžer verzija za JVM (Java, Kotlin, Gradle…)
-
SDKMAN : instalacija— Vodič za instalaciju SDKMAN.
-
gh` — GitHub CLI— GitHub, alat iz komandne linije, neophodan za svakog programera.
-
Gradle — zvanični sajt— Sistem gradnje kojeg instaliramo kroz SDKMAN.
-
pnpm — službeni sajt— Brži i prostorno efikasan menadžer paketa Node.js.
-
JetBrains Toolbox— Menadžer IDE JetBrains koji dodaje svoje skripte u PATH
Za daljnje istraživanje
-
Zsh dotfiles: kompletan priručnik— Detaljni članak o upravljanju dotfiles Zsh.
-
Zsh na ArchWiki— Jedna od najboljih zajedničkih dokumentacija za Zsh.
-
NVM problemi GitHub— Da biste videli rasprave oko simboličke veze`current`и проблеми са PATH.