PS1 = '$ (pwd)' mengapa ini bekerja dan mengapa ini berbeda dari PS1 = $ (pwd)

18

Mengapa ketika saya memasukkan perintah ini prompt berubah ke direktori saya?

PS1='$(pwd)'

Saya menggunakan tanda kutip tunggal, yang berarti tidak ada interpolasi, alias echo '$(pwd)'—— →$(pwd)

Lebih jauh, katakan bahwa kami mengklarifikasi mengapa ini berfungsi ... mengapa ini berfungsi secara berbeda PS1=$(pwd)? (tidak ada kutipan sama sekali)

Maksud saya adalah jika saya menggunakan tanda kutip maka prompt akan terus berubah ke direktori saya saat ini saat saya menavigasi melalui terminal. Tetapi jika saya tidak menggunakan tanda kutip, maka prompt akan selalu tetap direktori tempat saya berada ketika saya pertama kali memasukkan perintahPS1=$(pwd)

Mengapa?

HashWizard
sumber
2
Simpan beberapa siklus CPU dan gunakan PS1 = '$ PWD' yang
setara

Jawaban:

29

Ketika Anda hanya menetapkan nilai ke variabel, $(...)ekspresi dievaluasi kecuali jika diapit dengan tanda kutip tunggal (atau garis miring terbalik). Untuk memahami, coba dan bandingkan keduanya:

A=$(pwd)
echo "$A"
B='$(pwd)'
echo "$B"

Nilai Asegera menjadi string /home/yourusernamedan jelas tidak diingat dari mana string ini berasal, tetap sama bahkan jika Anda mengubah direktori. Nilai B, bagaimanapun, menjadi string literal $(pwd)tanpa ditafsirkan.

Sekarang, dalam nilai PS1sesuatu yang istimewa terjadi: setiap kali prompt dicetak, konstruksi khusus tertentu ditafsirkan, misalnya penggantian perintah $(...)dilakukan persis seperti yang terjadi di atas pada penugasan ke Avariabel. Tentunya jika Anda PS1berisi string literal dari direktori home Anda (seperti di atas dengan A) maka tidak ada cara itu bisa berubah. Tetapi jika itu berisi string $(pwd)(seperti di atas dengan B) maka itu dievaluasi setiap kali prompt dicetak dan karenanya direktori aktual Anda ditampilkan.

egmont
sumber
14

Baik dalam bash dan zsh, nilai PS1tidak digunakan sebagai prompt apa adanya, itu mengalami beberapa ekspansi. Aturan berbeda untuk dua kerang, tetapi dalam kedua kasus, salah satu langkah adalah untuk melakukan “dolar” ekspansi (variabel substitusi, substitusi perintah, evaluasi aritmatika) dengan sintaks yang sama seperti dalam sintaks shell normal ( , , atau , , ) .$VARIABLE${VARIABLE}$(COMMAND)`COMMAND`$((EXPRESSION))$[EXPRESSION]

  • Dalam bash, ekspansi dolar dihidupkan secara default, tetapi dapat dimatikan dengan shopt -u promptvars.
  • Di zsh, ekspansi dolar tidak aktif secara default, tetapi banyak orang (dan sebagian besar kerangka kerja konfigurasi yang Anda temukan di web) mengaktifkannya setopt prompt_subst.

Dengan ekspansi dolar pada prompt diaktifkan, PS1='$(pwd)'set PS1ke nilai 6-karakter $(pwd)dan dengan demikian menyebabkan $(pwd)diganti, dan karena itu pwdperintah yang akan dieksekusi, setiap kali shell menampilkan prompt baru. Di sisi lain, PS1=$(pwd)set PS1ke apa pun direktori aktif shell saat itu. Jika ekspansi dolar Anda dimatikan maka PS1='$(pwd)'akan menyebabkan prompt menjadi string literal $(pwd).

Perhatikan bahwa ada cara yang lebih nyaman untuk mendapatkan direktori kerja di prompt:

  • Dalam bash, dengan pelarian backslash seperti \w, yang menyingkat direktori home Anda ~dan dapat dipangkas dengan pengaturan PROMPT_DIRTRIM.
  • Di zsh, dengan persen melarikan diri seperti %/atau%~ ( %/sama dengan $PWD, %~menyingkat direktori home), yang dapat memiliki pengaturan pemangkasan.
  • Dalam kedua shell (dan shell Bourne-style lainnya), $PWDsama dengan $(pwd): Anda tidak perlu menjalankan subproses untuk mendapatkan direktori kerja saat ini.
Gilles 'SANGAT berhenti menjadi jahat'
sumber
7

Karena tanpa tanda kutip, $ (pwd) dievaluasi ketika PS1 diatur. Dengan tanda kutip, evaluasi $ (pwd) ditunda sampai prompt ditampilkan.

Tanpa tanda kutip, PS1 diatur ke direktori saat ini pada saat PS1 diatur. Dengan tanda kutip tunggal PS1 diatur ke $ (pwd), yang berarti akan mengevaluasi dan mencetak direktori saat ini setiap kali prompt ditampilkan.

farhangfarhangfar
sumber