Bab 15 menutup pembahasan produktivitas dengan reminder otomatis, integrasi clipboard/screenshot, dan dotfiles dasar berbasis Git plus symlink. Bab ini masuk lebih dalam ke satu lapisan yang selama ini baru disinggung sekilas: tampilan dan perilaku shell itu sendiri. Prompt default Bash yang polos, cuma menampilkan nama user dan direktori kerja, sebenarnya bisa diubah total jadi lebih informatif, misalnya langsung menampilkan branch Git aktif tanpa perlu mengetik git status berulang kali. Alias dan function dari Bab 13.4 juga bisa dikembangkan jadi kumpulan shortcut yang benar-benar mempercepat kerja harian User, bukan sekadar dua tiga contoh dasar. Bab ini membahas empat hal: kustomisasi prompt lewat variabel PS1 dan tema terminal, kumpulan alias/function/shortcut yang berguna, sekilas perkenalan shell lain (zsh dan fish) beserta implikasinya terhadap kompatibilitas script, dan ditutup studi kasus membangun dotfiles pribadi yang portable lintas shell.
16.1 Kustomisasi Prompt (PS1) dan Tema Terminal
Sub-bab ini membahas cara mengubah tampilan prompt Bash lewat variabel PS1, mulai dari escape sequence dasar sampai menambahkan warna dan informasi branch Git secara otomatis.
16.1.1 Anatomi PS1 dan Escape Sequence Dasar
PS1 (Primary Prompt String) adalah variabel shell yang menentukan tampilan prompt utama Bash, baris yang muncul setiap kali shell menunggu perintah baru diketik. Menurut GNU Bash Reference Manual bagian "Controlling the Prompt", nilai PS1 bukan sekadar teks polos; ia mendukung sederet escape sequence berawalan backslash yang diterjemahkan Bash jadi informasi dinamis setiap kali prompt dicetak ulang.
echo "$PS1"Perintah di atas menampilkan nilai PS1 yang sedang aktif di sesi kita saat ini, biasanya berupa kombinasi beberapa escape sequence default bawaan distro. Tabel berikut merangkum escape sequence yang paling sering dipakai, diambil dari daftar lengkap di dokumentasi resmi Bash.
| Escape | Arti |
|---|---|
\u | Nama user yang sedang login |
\h | Hostname, sampai titik pertama saja |
\w | Direktori kerja saat ini, $HOME disingkat ~ |
\W | Hanya nama folder terakhir dari direktori kerja |
\t | Waktu format 24 jam HH:MM:SS |
\d | Tanggal format "Hari Bulan Tanggal" |
\n | Baris baru |
\$ | Tanda $, otomatis berubah jadi # kalau dijalankan sebagai root |
Contoh paling sederhana menggabungkan beberapa escape ini jadi satu prompt kustom.
PS1='\u@\h:\w\$ 'Prompt di atas menampilkan pola user@hostname:/path/direktori$, mirip tampilan default kebanyakan distro tapi ditulis eksplisit supaya kita paham betul dari mana tiap bagiannya berasal. Ketik langsung baris ini di terminal untuk melihat efeknya seketika; perubahan ini masih sementara dan hilang begitu sesi shell ditutup, sama seperti alias yang belum disimpan permanen di Bab 13.4.2.
16.1.2 Menambahkan Warna dengan ANSI Escape Code
Terminal modern menafsirkan urutan karakter khusus yang disebut ANSI escape code untuk mengubah warna teks, bukan cuma menampilkannya apa adanya. Kode ini diawali karakter escape (\033 dalam notasi oktal) diikuti kurung siku dan kode warna, lalu ditutup huruf m.
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ 'Kode 01;32 berarti hijau cerah (bold), 01;34 berarti biru cerah, dan 00 mengembalikan warna ke kondisi normal. Bagian yang paling gampang terlewat, dan menurut dokumentasi resmi Bash memang wajib, adalah membungkus kode warna itu dengan \[ di awal dan \] di akhir. Kedua penanda ini memberi tahu Bash bahwa teks di antaranya adalah karakter non-printing, tidak benar-benar menempati ruang visual di layar, sehingga Bash bisa menghitung panjang prompt yang sesungguhnya dengan tepat. Tanpa \[ dan \], Bash ikut menghitung kode warna sebagai karakter biasa, dan efeknya baru terasa saat baris perintah yang diketik cukup panjang sampai perlu wrap ke baris berikutnya: posisi kursor jadi meleset dari posisi seharusnya, membuat riwayat perintah yang dipanggil ulang lewat tombol panah atas terlihat berantakan di layar.
Menghafal kode ANSI mentah cukup merepotkan, jadi alternatif yang lebih portable adalah memakai tput, tool standar yang membaca database terminfo dan menerjemahkan permintaan warna ke kode yang sesuai untuk terminal yang sedang dipakai.
hijau=$(tput setaf 2)
reset=$(tput sgr0)
PS1="\[${hijau}\]\u@\h\[${reset}\]:\w\$ "tput setaf 2 menghasilkan kode warna hijau (nomor warna ANSI standar 0-7: hitam, merah, hijau, kuning, biru, magenta, cyan, putih), dan tput sgr0 mengembalikan ke kondisi normal. Karena keduanya disimpan lebih dulu ke variabel biasa lewat command substitution (Bab 3.4.4), penanda \[ dan \] tetap perlu dituliskan manual mengelilingi referensi variabelnya di dalam PS1, seperti dicontohkan di atas, supaya aturan penghitungan panjang prompt tadi tetap berlaku.
16.1.3 Menampilkan Branch Git di Prompt
Salah satu kustomisasi paling berguna untuk Developer maupun User yang sering bekerja dengan repository Git adalah menampilkan nama branch yang sedang aktif langsung di prompt, tanpa perlu mengetik git status setiap kali ingin memastikan berada di branch mana. Bungkus dulu logikanya jadi sebuah function.
parse_git_branch() {
local branch
branch=$(git symbolic-ref --short HEAD 2>/dev/null)
[[ -n "$branch" ]] && echo " ($branch)"
}
PS1='\u@\h:\w$(parse_git_branch)\$ 'git symbolic-ref --short HEAD mengembalikan nama branch aktif dalam bentuk singkat, sesuai dokumentasi resmi Git; perintah ini gagal dengan pesan error kalau direktori kerja bukan repository Git sama sekali, sehingga 2>/dev/null dari Bab 5.3.3 dipakai membungkam pesan errornya, dan pengujian [[ -n "$branch" ]] dari Bab 6.2.2 memastikan tanda kurung nama branch cuma muncul kalau memang sedang berada di dalam repository. Bagian penting yang sering luput: pemanggilan $(parse_git_branch) ditulis langsung di dalam nilai PS1, bukan dieksekusi sekali lalu hasilnya ditempel sebagai teks statis. Menurut dokumentasi resmi Bash, isi PS1 memang mengalami command substitution setiap kali prompt akan dicetak ulang, sehingga branch yang ditampilkan otomatis berubah setiap kali kita berpindah direktori atau branch, tanpa perlu menjalankan ulang apa pun secara manual.
Di lapangan, pendekatan ini punya satu trade-off yang jujur perlu disebutkan: karena parse_git_branch dipanggil ulang setiap prompt dicetak, repository yang sangat besar bisa membuat jeda singkat sebelum prompt tampil, meski untuk kebanyakan repository ukuran wajar efeknya nyaris tidak terasa.
16.1.4 Menyimpan Prompt Permanen dan Alternatif Tema Instan
Sama seperti alias dan function di Bab 13.4.2, baris PS1 kustom perlu ditulis di ~/.bashrc supaya permanen dan otomatis aktif setiap sesi terminal baru dibuka, bukan diketik ulang manual setiap kali.
echo 'PS1="\u@\h:\w\$ "' >> ~/.bashrc
source ~/.bashrcSelain menyusun PS1 manual, variabel PROMPT_COMMAND juga tersedia untuk kebutuhan yang lebih kompleks dari sekadar string. Menurut dokumentasi resmi Bash, isi PROMPT_COMMAND dieksekusi tepat sebelum setiap prompt utama dicetak, cocok dipakai untuk logika tambahan seperti memperbarui judul jendela terminal secara dinamis mengikuti direktori kerja saat ini.
PROMPT_COMMAND='echo -ne "\033]0;${PWD##*/}\007"'Pola ${PWD##*/} di atas memakai parameter expansion serakah dari Bab 13.1.2 untuk mengambil nama folder terakhir dari $PWD. Perlu dicatat, urutan escape \033]0;...\007 ini mengikuti konvensi kontrol xterm yang didukung luas oleh banyak terminal emulator turunan xterm (GNOME Terminal, Konsole, iTerm2, dan sejenisnya), tapi dukungannya tetap bergantung terminal emulator yang dipakai, jadi uji dulu di terminal masing-masing sebelum diandalkan.
Menyusun prompt manual seperti di atas memang butuh waktu, tapi bukan satu-satunya jalan. Starship adalah tool prompt pihak ketiga yang bekerja lintas shell (Bash, zsh, fish, dan lainnya), menyediakan tema siap pakai plus deteksi otomatis konteks proyek (versi bahasa pemrograman, status Git, dan sejenisnya) tanpa perlu menulis function seperti 16.1.3 sendiri. Menurut dokumentasi resminya di starship.rs, instalasi paling umum lewat package manager distro atau script instalasi resmi.
curl -sS https://starship.rs/install.sh | shSebagai kebiasaan aman, apa pun script instalasi yang dijalankan lewat curl | sh seperti ini sebaiknya ditinjau dulu isinya (misalnya dibuka lewat browser terlebih dulu) sebelum benar-benar dieksekusi, mengingat prinsip kehati-hatian yang sama juga berlaku untuk script apa pun yang dijalankan dengan hak akses kita. Setelah terpasang, aktivasi Starship di Bash cukup satu baris tambahan di ~/.bashrc, sesuai dokumentasi resminya.
eval "$(starship init bash)"Tema Starship sendiri diatur lewat file konfigurasi terpisah, ~/.config/starship.toml, di luar cakupan PS1 bawaan Bash yang sudah dibahas di sub-bab ini. Untuk kebutuhan yang sederhana, pendekatan manual 16.1.1 sampai 16.1.3 tetap cukup dan tidak menambah dependency di luar Bash itu sendiri; Starship lebih relevan kalau kustomisasi yang diinginkan sudah cukup rumit atau perlu konsisten dipakai di lebih dari satu shell, topik yang dibahas lebih lanjut di 16.3.
16.2 Alias, Function, dan Shortcut yang Berguna
Bab 13.4 sudah menjelaskan dasar perbedaan alias dan shell function serta cara menyimpannya permanen di .bashrc. Sub-bab ini melangkah lebih jauh: kumpulan shortcut praktis yang benar-benar layak ditambahkan ke konfigurasi shell harian User, dikelompokkan per kebutuhan.
16.2.1 Alias Navigasi dan Keamanan
Berpindah direktori ke folder induk adalah salah satu perintah paling sering diketik ulang; alias pendek berikut memangkasnya jadi dua atau tiga karakter saja.
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'Untuk kebutuhan berpindah lebih dari beberapa tingkat sekaligus dengan jumlah level yang fleksibel, alias saja tidak cukup karena alias tidak bisa menerima argumen secara dinamis, sebagaimana sudah dijelaskan di Bab 13.4.1. Function up berikut menerima jumlah level sebagai argumen.
up() {
local n=${1:-1}
local path=""
for ((i = 0; i < n; i++)); do
path="../$path"
done
cd "$path" || return 1
}${1:-1} memakai nilai default dari Bab 6.4.4, membuat up tanpa argumen otomatis naik satu level, sama seperti alias .., sementara up 3 naik tiga level sekaligus. for ((...)) memakai C-style for loop dari Bab 7.1.3 untuk merangkai path ../../../ sebanyak n kali sebelum akhirnya di-cd-kan.
Alias keamanan berikut menambahkan konfirmasi interaktif untuk tiga perintah yang sifatnya merusak kalau salah ketik, memakai opsi -i yang sudah disinggung di Bab 13.1.4.
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'Perlu jujur dicatat satu batasan alias jenis ini: alias hanya berlaku saat perintah dipanggil persis dengan nama itu di sesi interaktif. Kalau perintah yang sama dipanggil dari dalam script (Bab 8), atau dipanggil lewat path penuh seperti /bin/rm, alias ini tidak ikut aktif, karena menurut dokumentasi resmi Bash, ekspansi alias memang khusus berlaku untuk shell interaktif dan tidak diwariskan ke script non-interaktif. Alias ini pas jadi jaring pengaman untuk pemakaian manual sehari-hari, tapi jangan pernah dijadikan satu-satunya lapisan proteksi di dalam script otomatis; script tetap wajib eksplisit menuliskan opsi -i atau -n sendiri seperti dicontohkan di Bab 13.1.4, bukan mengandalkan alias yang kebetulan aktif di sesi interaktif kita.
16.2.2 Alias untuk Git
Developer maupun User yang rutin memakai Git bisa memangkas banyak ketikan lewat kumpulan alias singkat berikut.
alias gs='git status'
alias ga='git add'
alias gc='git commit -m'
alias gp='git push'
alias gl='git log --oneline --graph --decorate'Alias gc di atas dipakai dengan pola gc "pesan commit", karena alias murni substitusi teks sesuai penjelasan Bab 13.4.1: gc "Perbaiki bug validasi" secara efektif dijalankan sebagai git commit -m "Perbaiki bug validasi". Alias gl memakai opsi --graph dan --decorate dari git log untuk menampilkan riwayat commit dalam bentuk grafik bercabang yang ringkas, sesuai dokumentasi resmi Git, jauh lebih gampang dipindai dibanding output git log polos yang menampilkan detail penuh tiap commit.
16.2.3 Mengatur Riwayat Perintah (History)
Riwayat perintah yang tersimpan rapi juga bagian dari kustomisasi shell yang sering diabaikan. Tiga variabel berikut, sesuai dokumentasi resmi Bash bagian "Bash History Facilities", mengatur seberapa banyak dan bagaimana riwayat perintah disimpan.
HISTSIZE=10000
HISTFILESIZE=20000
HISTCONTROL=ignoredups:erasedups
shopt -s histappendHISTSIZE membatasi jumlah baris riwayat yang disimpan di memori selama sesi berjalan, sedangkan HISTFILESIZE membatasi jumlah baris yang disimpan permanen di file ~/.bash_history. HISTCONTROL=ignoredups:erasedups mencegah perintah yang sama persis dicatat berulang-ulang kalau diketik berturut-turut (ignoredups), sekaligus menghapus duplikat lama di riwayat kalau perintah yang sama diketik ulang di lain waktu (erasedups). shopt -s histappend mengubah perilaku default Bash yang menimpa file riwayat setiap sesi ditutup, menjadi menambahkan (append) riwayat sesi itu ke file yang sudah ada, penting terutama kalau kita sering membuka banyak jendela terminal sekaligus, supaya riwayat dari satu jendela tidak menimpa riwayat jendela lain yang ditutup lebih dulu.
Setelah baris ini masuk ke .bashrc dan sesi baru dibuka, tombol panah atas atau pencarian riwayat lewat Ctrl+R, fitur bawaan readline yang dipakai Bash, langsung terasa lebih rapi karena tidak lagi dipenuhi baris duplikat.
16.2.4 Mengelola Banyak Alias dengan File Terpisah
Begitu jumlah alias dan function bertambah banyak, menumpuknya semua langsung di .bashrc membuat file itu cepat penuh dan susah dipindai. Kebiasaan yang umum dipraktikkan, dan sudah jadi bagian dari .bashrc bawaan beberapa distro seperti Debian dan Ubuntu, adalah memisahkan alias ke file ~/.bash_aliases tersendiri, lalu memuatnya dari .bashrc lewat pengecekan berikut.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fiCek dulu apakah blok ini sudah ada di .bashrc bawaan sistem kita lewat grep bash_aliases ~/.bashrc, karena tidak semua distro menyertakannya secara default; kalau belum ada, tambahkan manual seperti contoh di atas. Setelah blok ini aktif, seluruh alias dari 16.2.1 dan 16.2.2 tinggal dipindah ke ~/.bash_aliases, sementara .bashrc sendiri tetap ringkas, isinya cuma pengaturan shell inti seperti PS1 dan variabel history dari sub-bab sebelumnya.
16.3 Shell Lain: zsh dan fish
Sub-bab ini membahas dua shell alternatif populer di luar Bash, zsh dan fish, serta implikasinya terhadap script Bash yang sudah kita tulis sepanjang series ini.
16.3.1 Kenapa Ada Shell Selain Bash
Bash bukan satu-satunya shell yang tersedia di ekosistem Unix-like. Zsh (Z shell) adalah shell yang dibangun sebagai superset dari sh, menambahkan fitur seperti auto-completion yang jauh lebih pintar, spelling correction, dan sistem plugin populer seperti Oh My Zsh. Sejak macOS Catalina (rilis tahun 2019), Apple menjadikan zsh sebagai shell default menggantikan Bash, salah satu alasan kenapa Bash bawaan macOS masih terjebak di versi lama seperti sudah disinggung di Bab 1.3.2. Fish (Friendly Interactive Shell) mengambil arah lebih radikal: menurut dokumentasi resminya di fishshell.com, fish sengaja dirancang dengan sintaks sendiri yang tidak mengikuti standar POSIX Shell sama sekali, demi kenyamanan interaktif seperti syntax highlighting dan saran autocomplete yang aktif langsung saat mengetik, tanpa perlu plugin tambahan seperti di Bash atau zsh.
Untuk mencoba salah satu atau keduanya secara langsung, zsh dan fish tersedia lewat package manager standar di kebanyakan distro Linux, tanpa perlu kompilasi manual dari source.
# Debian/Ubuntu
sudo apt install zsh fish
# Fedora
sudo dnf install zsh fish
# Arch Linux
sudo pacman -S zsh fishDi macOS, zsh sudah terpasang bawaan sejak Catalina seperti disebutkan di atas, sedangkan fish perlu dipasang terpisah, paling praktis lewat Homebrew yang sudah diperkenalkan di Bab 1.3.2.
brew install fishInstalasi ini hanya menambahkan shell baru sebagai pilihan; ia belum otomatis jadi shell login default kita, langkah yang dibahas terpisah di 16.3.3. Cek shell mana yang tercatat sebagai default login kita saat ini lewat variabel $SHELL.
echo "$SHELL"Perlu dicatat, $SHELL mencerminkan shell login yang tercatat di /etc/passwd, bukan selalu shell yang benar-benar sedang berjalan saat itu juga. Kalau kita membuka sesi Bash secara manual dari dalam zsh, misalnya lewat mengetik bash, $SHELL tetap menampilkan zsh sebagai shell login meski perintah yang sedang diketik saat itu diproses Bash. Cara yang lebih akurat memeriksa shell yang benar-benar aktif saat ini adalah lewat ps dari Bab 17 nanti, atau cukup memeriksa variabel khas tiap shell seperti $BASH_VERSION dan $ZSH_VERSION.
ps -p $$ -o comm=16.3.2 Perbedaan Sintaks yang Perlu Diwaspadai
Zsh secara umum jauh lebih kompatibel dengan Bash dibanding fish, tapi tetap punya beberapa perbedaan mendasar yang bisa mengejutkan kalau tidak diketahui lebih dulu. Menurut dokumentasi resmi zsh, indeks array di zsh dimulai dari 1 secara default, berbeda dengan Bash yang selalu dimulai dari 0 seperti sudah dibahas di Bab 4.1.1. Fish melangkah lebih jauh lagi: sintaksnya benar-benar berbeda, bukan cuma sedikit variasi dari POSIX Shell. Tabel berikut merangkum beberapa perbedaan inti yang paling sering ditemui saat berpindah antar ketiga shell ini.
| Aspek | Bash | zsh | fish |
|---|---|---|---|
| Indeks array pertama | 0 | 1 (default) | 1 |
| Set variabel | nama=nilai | nama=nilai | set nama nilai |
| Kondisi test | [[ ... ]] | [[ ... ]] | test ... / [ ... ] |
Kompatibel POSIX sh | Ya (mode --posix) | Ya (mode emulasi) | Tidak |
Fish juga tidak mengenal export terpisah seperti Bab 3.2.2; menjadikan sebuah variabel sebagai environment variable cukup lewat opsi tambahan pada set itu sendiri, sesuai dokumentasi resminya.
# Bash
export EDITOR=vim
# fish
set -x EDITOR vimDetail lengkap sintaks fish di luar cakupan series ini yang fokus pada Bash; kalau kita memang memilih memakai fish sebagai shell interaktif sehari-hari, dokumentasi resmi di fishshell.com adalah rujukan paling lengkap dan akurat untuk mempelajari sintaksnya lebih jauh.
16.3.3 Menjaga Script Bash Tetap Portable
Perbedaan sintaks di 16.3.2 memunculkan pertanyaan penting: kalau shell login default kita sudah diganti jadi zsh atau fish, apakah semua script Bash yang sudah ditulis sepanjang series ini masih bisa jalan? Jawabannya, selama shebang yang sudah diperkenalkan di Bab 1.4.1 dituliskan dengan benar, iya, tetap bisa. Shebang #!/bin/bash di baris pertama script memaksa kernel menjalankan isi file itu memakai interpreter Bash, apa pun shell interaktif yang sedang kita pakai untuk memanggil script tersebut. Shell login hanya menentukan lingkungan tempat kita mengetik perintah secara interaktif; begitu sebuah file script dieksekusi lewat ./nama-script.sh, kernel membaca baris shebang-nya dan mengalihkan eksekusi sepenuhnya ke interpreter yang tertulis di sana, terlepas dari shell interaktif apa pun yang sedang aktif.
Konsekuensinya, mengganti shell login lewat chsh (change shell) sama sekali tidak memengaruhi cara script Bash yang sudah ditulis berjalan, selama shebang-nya tetap eksplisit menunjuk /bin/bash.
cat /etc/shells
chsh -s /bin/zsh/etc/shells berisi daftar shell yang terdaftar sah di sistem, dan chsh -s mengubah shell login yang tercatat untuk user kita di /etc/passwd, sesuai man page chsh. Perlu dicatat, perubahan ini biasanya baru terasa efeknya di sesi login berikutnya, bukan seketika di sesi yang sedang berjalan saat perintah chsh dieksekusi. Satu jebakan yang sering luput disadari: kalau sebuah script ditulis tanpa shebang sama sekali, lalu dijalankan lewat sh nama-script.sh atau di-source langsung dari sesi shell yang kebetulan bukan Bash, fitur-fitur khas Bash yang sudah dipakai sepanjang series ini, seperti array (Bab 4), [[ ]] (Bab 6.1.3), atau ${var,,} untuk case conversion (Bab 9.4.4), bisa gagal atau berperilaku beda karena diproses interpreter yang berbeda. Kebiasaan aman yang berlaku sejak Bab 1.4.1 tetap berlaku di sini: selalu sertakan shebang #!/bin/bash secara eksplisit, dan jalankan script lewat ./nama-script.sh, bukan sh nama-script.sh, supaya interpreter yang dipakai selalu pasti Bash.
16.4 Studi Kasus: Dotfiles Portable Lintas Shell
Bab 15.3 sudah membangun fondasi dotfiles berbasis Git dan symlink, dikelola rapi lewat GNU Stow. Studi kasus penutup ini memperluas fondasi itu supaya alias dan function favorit kita tetap bisa dipakai konsisten, baik saat sesi shell yang aktif kebetulan Bash maupun zsh, tanpa perlu menulis dua salinan konfigurasi yang saling terpisah dan gampang tidak sinkron.
16.4.1 Rancangan: Satu Sumber Konfigurasi untuk Dua Shell
Alias sederhana dan function yang hanya memakai sintaks dasar seperti pada 16.2.1 dan 16.2.2 sebenarnya kompatibel dijalankan di Bash maupun zsh apa adanya, mengingat kompatibilitas luas zsh terhadap sintaks Bash yang sudah disinggung di 16.3.2. Bagian yang tidak portable justru PS1: escape sequence \u, \h, \w dari 16.1.1 adalah konvensi khas Bash, sedangkan zsh memakai sistem escape sendiri berawalan % (%n untuk username, %m untuk hostname, %~ untuk direktori kerja), sesuai dokumentasi resmi zsh bagian "Prompt Expansion". Rancangan yang masuk akal: pisahkan alias dan function yang portable ke satu file bersama, sementara pengaturan PS1 yang spesifik per shell tetap ditulis terpisah di file konfigurasi masing-masing.
16.4.2 Implementasi File Konfigurasi Bersama
Tambahkan folder baru shell/ ke dalam struktur dotfiles yang sudah dibangun di Bab 15.3.2, berisi satu file common.sh yang memuat seluruh alias dan function portable.
# ~/dotfiles/shell/common.sh
alias ..='cd ..'
alias ...='cd ../..'
alias gs='git status'
alias gl='git log --oneline --graph --decorate'
mkcd() {
mkdir -p "$1" && cd "$1" || return 1
}
up() {
local n=${1:-1}
local path=""
for ((i = 0; i < n; i++)); do
path="../$path"
done
cd "$path" || return 1
}File ini murni kumpulan definisi, tidak dijalankan langsung; ia perlu di-source dari file konfigurasi shell masing-masing. Untuk Bash, tambahkan blok berikut ke ~/.bashrc, diletakkan setelah bagian yang memuat .bash_aliases dari 16.2.4 kalau ada.
# ~/.bashrc
if [ -f ~/dotfiles/shell/common.sh ]; then
. ~/dotfiles/shell/common.sh
fi
PS1='\u@\h:\w$(parse_git_branch)\$ 'Untuk zsh, blok yang setara ditulis di ~/.zshrc, file konfigurasi interaktif zsh yang setara dengan .bashrc di Bash, sesuai dokumentasi resmi zsh bagian "Startup/Shutdown Files".
# ~/.zshrc
if [ -f ~/dotfiles/shell/common.sh ]; then
. ~/dotfiles/shell/common.sh
fi
setopt PROMPT_SUBST
PS1='%n@%m %~ %# 'Baris setopt PROMPT_SUBST penting ditambahkan kalau PS1 zsh nanti ingin memuat pemanggilan function seperti parse_git_branch dari 16.1.3. Menurut dokumentasi resmi zsh, tanpa opsi ini command substitution dan pemanggilan function di dalam PS1 tidak otomatis dieksekusi ulang setiap prompt dicetak, berbeda dengan Bash yang sudah melakukannya secara default seperti dijelaskan di 16.1.3. Karena keduanya sekarang sama-sama memuat common.sh yang sama persis, alias gs, gl, function mkcd, dan up otomatis tersedia identik di kedua shell, sementara baris PS1 tetap ditulis terpisah sesuai sintaks masing-masing.
Perlu jujur diakui, pendekatan file bersama ini tidak berlaku untuk fish, karena seperti sudah dibahas di 16.3.2, fish tidak memproses sintaks alias nama='perintah' maupun function nama() { ... } dengan cara yang sama persis. Fish menyediakan builtin alias sendiri yang secara internal diterjemahkan jadi function fish, dan definisi function fish ditulis dengan blok function ... end, bukan kurung kurawal. Kalau dotfiles ini nanti perlu mendukung fish juga, cara paling jujur dan aman adalah menulis file konfigurasi terpisah, misalnya ~/.config/fish/config.fish, dengan sintaks fish native-nya sendiri, alih-alih memaksakan common.sh supaya bisa dibaca fish, yang berisiko menghasilkan alias atau function yang gagal atau berperilaku salah tanpa pesan error yang jelas.
16.4.3 Verifikasi Portabilitas
Setelah struktur di atas disimpan, perbarui juga langkah instalasi lewat Stow dari Bab 15.3.2 supaya folder shell/ ikut di-symlink.
cd ~/dotfiles
stow shellVerifikasi di sesi Bash, alias dan function harus dikenali seperti biasa lewat type dari Bab 13.4.4.
type mkcd
type up
alias gsKalau zsh sudah terpasang di sistem (banyak distro menyediakannya lewat package manager, atau sudah tersedia bawaan seperti di macOS), buka sesi zsh sesaat lewat mengetik zsh, lalu ulangi pengecekan yang sama.
zsh
type mkcd
type up
alias gsKalau common.sh sudah benar di-source dari .zshrc, ketiganya harus dikenali persis sama seperti di sesi Bash, dan PS1 menampilkan format khas zsh dari 16.4.2, bukan format Bash. Keluar dari sesi zsh lewat exit untuk kembali ke sesi Bash semula. Struktur ini menyatukan empat topik yang dibahas sepanjang bab ini, prompt, alias/function, sekilas shell lain, dan dotfiles portable, jadi satu kebiasaan kerja yang konsisten, tidak peduli shell interaktif mana yang kebetulan sedang aktif di komputer yang dipakai. Bagian 2 series ini resmi ditutup di sini; Bagian 3 dimulai dari Bab 17, berpindah fokus dari otomatisasi desktop pribadi ke administrasi server, dimulai dari perintah dasar mengecek kondisi sistem.

