Linux

Kenapa Tilde di PATH Bash dan Zsh Tidak Selalu Jadi Home

Kenapa Tilde di PATH Bash dan Zsh Tidak Selalu Jadi Home

Menulis export PATH="$PATH:~/.local/bin/" di berkas konfigurasi shell tidak menambahkan direktori home Anda ke PATH. Sebaliknya, shell menambahkan entri literal yang berisi karakter tilde, dan entri itu diperlakukan sebagai jalur relatif terhadap direktori kerja saat perintah dijalankan. Temuan ini dipublikasikan disconnect3d pada 2 Oktober 2026, dan ia menemukannya saat alat sandbox nono memperingatkan bahwa ada entri PATH yang bisa ditulis oleh sandbox.

TL;DR

  • Ekspansi tilde hanya terjadi pada input yang tidak dikutip, jadi tilde di dalam tanda kutip tidak berubah menjadi direktori home.
  • Akibatnya, entri PATH yang ditambahkan adalah jalur relatif seperti ./~/.local/bin/, bukan /home/pengguna/.local/bin/.
  • Bentuk tanpa kutip export PATH=$PATH:~/.local/bin memang bekerja di bash dan zsh, tetapi rapuh karena spasi saja bisa memutusnya.
  • Cara paling aman adalah memakai $HOME secara eksplisit di dalam tanda kutip.
  • Masalah ini bisa menjadi celah keamanan kalau ada program jahat yang diletakkan di direktori relatif tersebut.

Kenapa tilde di PATH tidak selalu jadi direktori home?

Karena ekspansi tilde hanya dilakukan pada input yang tidak dikutip. Dokumentasi resmi bash menyatakan bahwa sebuah kata dianggap punya prefiks tilde hanya kalau kata itu diawali karakter tilde yang tidak dikutip. Bash juga memeriksa setiap penugasan variabel untuk prefiks tilde yang tidak dikutip tepat setelah tanda titik dua atau tanda sama dengan pertama, dan melakukan ekspansi tilde pada kasus itu. Begitu tilde berada di dalam tanda kutip, aturan tersebut tidak berlaku.

Dalam praktiknya, ini berarti export PATH="$PATH:~/.local/bin/" menghasilkan entri yang benar-benar berisi karakter tilde. Direktori home tidak pernah disentuh. Penulis artikel mendemonstrasikannya dengan sengaja membuat direktori bernama tilde di dalam direktori kerja, menaruh sebuah program di sana, lalu menjalankannya lewat PATH yang berisi entri tersebut. Program itu ditemukan dan dieksekusi dari direktori relatif, bukan dari home. Jadi shell tidak salah; ia hanya mengikuti aturan ekspansi yang berlaku, dan aturan itu tidak sesuai dengan yang diasumsikan banyak orang.

Yang menarik, masalah ini sering tidak terasa sampai ada alat lain yang menunjukkannya. Dalam kasus ini, alat sandbox nono memunculkan peringatan bahwa ada entri PATH yang bisa ditulis oleh sandbox. Peringatan itu yang memicu penyelidikan lebih lanjut. Ini contoh bagaimana pengamatan dari alat pihak ketiga bisa mengungkap kesalahan konfigurasi yang sudah lama tidak terlihat.

Apa bedanya versi berkutip dan tidak berkutip?

Bedanya ada pada apakah shell melakukan ekspansi tilde saat menetapkan nilai variabel. Versi berkutip tidak mengekspansi, sedangkan versi tidak berkutip mengekspansi di bash dan zsh karena tilde mengikuti tanda titik dua dalam penugasan. Meski begitu, mengandalkan versi tidak berkutip tetap rapuh.

Bentuk penulisanEkspansi tildeHasil entri PATH
export PATH="$PATH:~/.local/bin/"TidakEntri literal berisi tilde, diperlakukan sebagai jalur relatif
export PATH=$PATH:~/.local/binYa, di bash dan zshJalur absolut ke direktori home
export PATH="$PATH:$HOME/.local/bin/"Tidak perluJalur absolut yang eksplisit dan paling aman

Menurut penulisnya, versi tidak berkutip memang bekerja karena ekspansi tilde juga dilakukan pada penugasan variabel setelah tanda sama dengan dan setelah setiap titik dua. Namun ia menyebut pendekatan itu rapuh karena satu spasi saja bisa memutus penugasan variabel. Artinya, bentuk yang tampak bekerja bisa berhenti bekerja setelah penyuntingan kecil yang tampak tidak berbahaya. Karena itu, memakai $HOME secara eksplisit lebih dapat diandalkan.

Bagaimana cara memeriksa dan memperbaiki PATH?

Periksa apakah PATH Anda mengandung entri bertilde dengan menyaring isi variabel PATH memakai grep. Kalau perintah itu mencetak apa pun, berarti ada entri bertilde yang perlu diperbaiki. Pemeriksaan ini cepat dan bisa dijalankan di shell apa pun yang Anda pakai.

Kalau ditemukan, buka berkas konfigurasi shell yang relevan, misalnya berkas yang dibaca oleh bash atau zsh saat memulai sesi, lalu ganti setiap tilde di dalam penetapan PATH dengan $HOME. Contohnya, ubah export PATH="$PATH:~/.local/bin/" menjadi export PATH="$PATH:$HOME/.local/bin/". Setelah menyimpan, mulai sesi shell baru atau muat ulang berkas konfigurasi itu, lalu jalankan pemeriksaan sekali lagi untuk memastikan entri bertilde sudah hilang.

Satu catatan praktis: masalah ini tidak selalu muncul sebagai error. Shell tidak akan mengeluh, dan perintah Anda tetap berjalan. Yang berubah hanya dari mana program dicari. Karena itu, memeriksa PATH secara berkala lebih berguna daripada menunggu gejala. Kalau Anda mengelola banyak mesin atau banyak akun, menyimpan pemeriksaan ini sebagai bagian dari skrip penyiapan lingkungan akan mencegah kesalahan yang sama terulang di setiap mesin baru.

Apakah ini masalah keamanan?

Bisa menjadi masalah keamanan, meski bukan eksploitasi langsung. Kalau PATH memuat jalur relatif, maka direktori yang dicari bergantung pada lokasi Anda menjalankan perintah. Siapa pun yang bisa menulis ke jalur relatif itu di dalam direktori kerja dapat menaruh program dengan nama yang sama seperti perintah yang Anda panggil, dan program itu akan dieksekusi lebih dulu. Prinsip ini sama dengan alasan mengapa menaruh titik di awal PATH dianggap berbahaya.

Dalam kasus ini, penulisnya tidak mengklaim adanya serangan yang sedang berlangsung. Yang ia tunjukkan adalah bahwa entri bertilde membuat direktori relatif masuk ke jalur pencarian, dan itu memperluas permukaan serangan. Peringatan dari alat sandbox nono menyorot aspek ini: entri PATH yang bisa ditulis oleh sandbox berarti sandbox punya jalur untuk memengaruhi apa yang dijalankan di luar batasnya. Bagi tim yang memakai sandbox atau isolasi serupa, memastikan PATH bersih dari jalur relatif adalah langkah pengerasan yang murah.

Selain itu, ada pelajaran yang lebih luas soal konfigurasi. Kesalahan seperti ini sering bertahan bertahun-tahun karena disalin dari satu berkas konfigurasi ke berkas lain, dan tidak ada yang memeriksanya kembali. Mengganti tilde dengan $HOME tidak hanya memperbaiki perilaku, tetapi juga membuat niat penulis konfigurasi menjadi eksplisit, sehingga pembaca berikutnya tidak perlu menebak apakah entri itu sengaja relatif atau tidak.

Apakah masalah tilde hanya soal PATH?

Tidak, akar masalahnya adalah asumsi bahwa tilde selalu dikembangkan, dan asumsi itu bisa muncul di tempat lain. Setiap kali Anda menulis tilde di dalam tanda kutip, baik di berkas konfigurasi shell, skrip, maupun berkas layanan, Anda berisiko mendapat karakter tilde literal, bukan jalur home. Pola yang sama bisa muncul pada variabel lain yang ditetapkan dengan tanda kutip, dan pada berkas yang tidak pernah melewati shell interaktif.

Berkas unit layanan adalah contoh yang sering terlewat. Ketika Anda mendefinisikan variabel lingkungan atau perintah yang dijalankan sebuah layanan, aturan ekspansi yang berlaku bukan aturan shell, dan tilde tidak selalu diterjemahkan seperti yang diharapkan. Karena itu, menulis jalur absolut atau memakai variabel yang sudah didefinisikan lebih aman daripada mengandalkan tilde. Prinsip umumnya sederhana: kalau Anda tidak yakin sebuah konteks melakukan ekspansi tilde, jangan bergantung padanya.

Hal yang sama berlaku untuk skrip yang dijalankan oleh penjadwal tugas. Penjadwal sering menjalankan perintah tanpa shell interaktif, sehingga tidak ada yang mengembangkan tilde maupun membaca berkas profil pengguna. Akibatnya, skrip yang bekerja saat Anda jalankan manual bisa gagal saat dijalankan terjadwal, dan penyebabnya bukan logika skrip, melainkan lingkungan yang berbeda. Menulis jalur secara eksplisit menghilangkan seluruh kelas kesalahan ini sebelum ia sempat membingungkan siapa pun.

Apa dampaknya untuk container dan otomasi?

Di dalam container, direktori home sering tidak berada di lokasi yang Anda duga, atau bahkan tidak ada sama sekali. Kalau sebuah skrip mengandalkan tilde untuk menemukan direktori home, perilakunya bisa berbeda dari satu image ke image lain. Ini alasan mengapa banyak panduan kontainer menganjurkan memakai variabel lingkungan eksplisit daripada mengandalkan ekspansi tilde. Kebiasaan yang sama berguna di luar container, karena membuat skrip Anda dapat dipindahkan antar lingkungan tanpa penyuntingan.

Untuk otomasi, implikasinya jelas: setiap jalur di dalam skrip sebaiknya absolut atau berasal dari variabel yang nilainya sudah pasti. Skrip yang bergantung pada direktori kerja saat dijalankan, atau pada ekspansi tilde yang tidak pasti, adalah skrip yang rapuh. Kerapuhan itu jarang muncul sebagai error di tahap pengujian karena di mesin pengembang semuanya tampak normal. Ia baru terlihat saat skrip berjalan di lingkungan lain, dan pada saat itu penyebabnya sering sulit dilacak karena tidak ada pesan kesalahan yang menunjuk ke masalah aslinya.

Ada juga sisi tinjauan kode yang jarang dibahas. Ketika seorang peninjau melihat penetapan PATH yang memakai tilde, pertanyaan yang tepat bukan hanya apakah ia bekerja, tetapi apakah ia bekerja untuk alasan yang benar. Kalau jawabannya bergantung pada aturan ekspansi yang halus, itu tanda bahwa penulisannya sebaiknya dibuat lebih eksplisit. Mengganti tilde dengan variabel home membuat niat penulis menjadi jelas dan menghilangkan ketergantungan pada detail yang mudah berubah antar shell. Konvensi semacam ini terlihat sepele, tetapi dalam jangka panjang ia mengurangi jumlah kejutan yang harus dihadapi saat memindahkan konfigurasi dari satu mesin ke mesin lain.

Pengaruh kesalahan ini bisa muncul 2 kali dalam alur yang sama: pertama saat PATH ditetapkan, ketika tilde gagal dikembangkan; kedua saat sebuah perintah dicari, ketika shell menelusuri jalur relatif yang terbentuk dari kesalahan itu. Keduanya berasal dari satu baris konfigurasi yang sama, sehingga memperbaikinya di sumbernya menyelesaikan dua gejala sekaligus.

Sumber dan bacaan lanjutan

Artikel ini merujuk pada tulisan penulis temuan dan dokumentasi resmi bash. Berikut tautan ke sumber primernya.

FAQ

Apakah semua shell punya perilaku ini?

Aturan ekspansi tilde hanya berlaku pada input tidak dikutip, dan itu berlaku umum. Perilaku ekspansi di dalam penugasan variabel dijelaskan untuk bash, dan zsh mengikuti pola serupa.

Apakah cukup mengganti tanda kutip saja?

Tidak selalu. Versi tidak berkutip memang bekerja, tetapi rapuh karena spasi bisa memutusnya. Memakai $HOME secara eksplisit lebih aman dan lebih jelas.

Bagaimana cara cepat mengecek PATH saya?

Jalankan pemeriksaan yang menyaring isi PATH memakai grep terhadap karakter tilde. Kalau ada hasil, berarti ada entri yang perlu diganti dengan $HOME.

Apakah ini bisa menyebabkan perintah salah dijalankan?

Ya. Karena entri relatif bergantung pada direktori kerja, program dengan nama sama di direktori itu bisa terpanggil lebih dulu daripada program yang Anda maksud.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar akan muncul setelah moderasi.