Sedikit bingung tentang apakah printf dalam yash shell adalah perintah bawaan atau tidak

14

The yashshell telah sebuah printfbuilt-in, menurut nya pengguna .

Namun, ini yang saya lihat di yashshell dengan konfigurasi default:

kk@eeyore ~ $ command -v printf
/usr/bin/printf
kk@eeyore ~ $ type printf
printf: a regular built-in at /usr/bin/printf

Apakah printfbuilt-in di shell ini atau tidak? Hasilnya serupa untuk sejumlah utilitas bawaan lain yang juga tersedia sebagai perintah eksternal.

Sebagai perbandingan, pada pdksh( kshpada OpenBSD, di mana printfadalah tidak built-in):

$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf

Dan di bash(mana printf adalah built-in):

$ command -v printf
printf
$ type printf
printf is a shell builtin
Kusalananda
sumber
1
Ini built-in - a biasa , bukan khusus built-in. Jika Anda bingung tentang perbedaan antara built-in khusus dan reguler , atau perilaku yang diamanatkan oleh standar (lihat pencarian perintah dan eksekusi 1.eia) - yang mensyaratkan biner harus ada PATHagar agar built-in reguler untuk dieksekusi - maka silakan ajukan pertanyaan Anda tentang itu.
Mosvy
1
@mosvy Ini adalah detail dari standar yang tidak saya ketahui. Jika Anda ingin mengubahnya menjadi jawaban, saya akan senang. Saya tidak berpikir saya perlu memperbarui pertanyaan untuk ini menjadi jawaban yang tepat, karena saya tidak mengetahui detail khusus ini. Atau saya akan menulis sendiri nanti.
Kusalananda

Jawaban:

14

The yashshell tidak memiliki, dan tidak digunakan, built-in versi printf(dan utilitas lainnya). Kebetulan POSIX sangat pedantically patuh dalam cara merumuskan hasil command -vdan typeperintah.

Seperti komentar mosvy , standar POSIX mensyaratkan bahwa perintah built-in reguler tersedia sebagai perintah eksternal $PATHuntuk menjalankan versi perintah built-in.

Ini adalah teks yang relevan dari standar :

Pencarian dan Eksekusi Perintah

Jika perintah sederhana menghasilkan nama perintah dan daftar argumen opsional, tindakan berikut harus dilakukan:

  1. Jika nama perintah tidak mengandung karakter <slash>, langkah sukses pertama dalam urutan berikut akan terjadi:

    • Sebuah. Jika nama perintah cocok dengan nama utilitas bawaan khusus, utilitas bawaan khusus itu akan dipanggil.

      [...]

    • e. Jika tidak, perintah harus dicari untuk menggunakan variabel lingkungan PATH seperti yang dijelaskan dalam Variabel Lingkungan XBD:
      • saya. Jika pencarian berhasil:
        • Sebuah. Jika sistem telah mengimplementasikan utilitas sebagai built-in biasa atau sebagai fungsi shell, ia harus dipanggil pada titik ini dalam pencarian path.
        • b. Jika tidak, shell mengeksekusi utilitas dalam lingkungan utilitas terpisah [...]
          [...]
      • ii. Jika pencarian tidak berhasil, perintah harus gagal dengan status keluar 127 dan shell akan menulis pesan kesalahan.
  2. Jika nama perintah mengandung setidaknya satu <slash>, [...]

Ini berarti bahwa output command -v printfmenandakan bahwa printfperintah itu ditemukan di jalur pencarian, sedangkan output type printfmenambahkan ini bahwa perintah adalah built-in biasa.

Karena printfperintah itu ditemukan di jalur pencarian, dan karena itu adalah built-in reguler di shell, yashakan memanggil versi built-in dari perintah . Jika printfitu tidak ditemukan di jalan, dan jika yashshell berjalan di POSIX-ly modus yang benar, kesalahan akan telah dihasilkan sebagai gantinya.

yashbangga menjadi shell yang sangat sesuai dengan POSIX, dan ini juga berlaku jika kita melihat apa yang dikatakan POSIX tentangcommand -v :

-v

Tulis string ke output standar yang menunjukkan pathname atau perintah yang akan digunakan oleh shell, di lingkungan eksekusi shell saat ini (lihat Lingkungan Eksekusi Shell ), untuk memanggil command_name, tetapi jangan meminta command_name.

  • Utilitas, utilitas built-in reguler , command_namestermasuk <slash>karakter, dan fungsi-fungsi yang didefinisikan implementasi yang ditemukan menggunakan PATHvariabel (seperti yang dijelaskan dalam Pencarian dan Eksekusi Perintah ), harus ditulis sebagai nama path absolut .
Kusalananda
sumber
3
Adakah yang tahu mengapa POSIX memiliki persyaratan untuk adanya perintah eksternal sebelum menjalankan perintah bawaan?
Studog
@studog Anda mungkin ingin menanyakannya sebagai pertanyaan baru yang terpisah, mungkin merujuk pada jawaban dan / atau pertanyaan ini.
Kusalananda
6

Shell Watanabe memiliki tiga macam built-in, yang dijelaskan secara rinci dalam manualnya. Semua perintah bawaan juga terdaftar di sana, tetapi kita harus menyimpulkan bahwa sesuatu adalah perintah bawaan "biasa" dari tidak adanya catatan yang mengatakan bahwa perintah itu adalah "khusus" atau "semi-khusus" built-in. Built-in reguler tidak ditandai.

printfadalah salah satu built-in "biasa" tersebut. Dalam mode asli selalu dipanggil, terlepas dari apakah ada perintah eksternal yang ditemukan oleh nama itu.

$ PATH = / usr / bin 
$ printf
printf: perintah ini membutuhkan operan
$ type printf
printf: built-in reguler di / usr / bin / printf
$
$ PATH = / 
$ printf
printf: perintah ini membutuhkan operan
$ type printf
printf: built-in biasa (tidak ditemukan dalam $ PATH)
$

Tetapi ketika posixly-correctopsi shell diatur itu hanya built-in jika perintah eksternal dapat ditemukan di PATH.

$ set --posixly-correct
$
$ PATH = / usr / bin 
$ printf
printf: perintah ini membutuhkan operan
$
$ PATH = / 
$ printf
yash: tidak ada perintah `printf '
$

Ini sebenarnya sesuai dengan apa yang dikatakan Single Unix Specification, dan telah mengatakan setidaknya sejak tahun 1997.

Ini berbeda dari shell Z, shell 93 Korn, shell Bourne Again, dan shell Debian Almquist, tidak ada yang menerapkan atau mendokumentasikan perilaku tersebut untuk built-in reguler. Shell Z, misalnya, dokumen yang selalu ada bawaan selalu ditemukan, sebelum langkah yang mencari PATH. Begitu juga shell Debian Almquist. Dan itulah yang dilakukan oleh semua shell ini, bahkan jika dipanggil seperti shopsi turn-on-POSIX mereka.

% / bin / exec -a sh zsh -c "PATH = /; ketik printf; printf"
printf adalah shell builtin
zsh: printf: 1: tidak cukup argumen
% / bin / exec -a sh ksh93 -c "PATH = /; ketik printf; printf"
printf adalah shell builtin
Penggunaan: format [opsi] printf [string ...]
% / bin / exec-bash sh --posix -c "PATH = / ketik printf; printf"
printf adalah shell builtin
printf: penggunaan: format printf [-v var] [argumen]
% / bin / exec-dasbor sh -c "PATH = /; ketik printf; printf"
printf adalah shell builtin
sh: 1: printf: penggunaan: format printf [arg ...]
% 

Namun, tidak berjalan printfsaat tidak aktif PATHadalah perilaku shell PD Korn, shell Heirloom Bourne, dan shell MirBSD Korn; karena mereka tidak memiliki printfbuilt-in di tempat pertama. ☺

% / bin / exec -a sh `command -v ksh` -c" PATH = /; ketik printf; printf "
printf tidak ditemukan
sh: printf: tidak ditemukan
% / bin / exec -a sh `command -v oksh` -c" PATH = /; ketik printf; printf "
printf tidak ditemukan
sh: printf: tidak ditemukan
% / bin / exec -a sh `command -v jsh` -c" PATH = /; ketik printf; printf "
printf tidak ditemukan
sh: printf: tidak ditemukan
% / bin / exec -a sh mksh -c "PATH = /; ketik printf; printf"
printf tidak ditemukan
sh: printf: tidak ditemukan
% ksh -c "ketik printf; printf"
printf adalah alias yang dilacak untuk / usr / bin / printf
penggunaan: format printf [argumen ...]
% oksh -c "ketik printf; printf"
printf adalah alias yang dilacak untuk / usr / bin / printf
penggunaan: format printf [argumen ...]
% jsh -c "ketik printf; printf"
printf di-hash (/ usr / bin / printf)
penggunaan: format printf [argumen ...]
% mksh -c "ketik printf; printf"
printf adalah alias yang dilacak untuk / usr / bin / printf
penggunaan: format printf [argumen ...]
$
JdeBP
sumber
Baik! Terima kasih telah mengonfirmasi dan menambahkan bit khusus shell ke pengetahuan saya! Saya sudah lebih suka shell ini.
Kusalananda
-1

Kata-katanya dapat ditingkatkan.

Jika shell dalam mode posix set --posixly-correct::

Untuk built-in reguler yang tidak ada di PATH ini dicetak:

pushd: a regular built-in (not found in $PATH)

Yang merupakan deskripsi yang jelas: Ini adalah builtin tetapi tidak ada yang dapat dieksekusi dengan nama yang sama di PATH.

Namun, untuk built-in reguler yang namanya juga ada di PATH, ini dicetak:

echo: a regular built-in at /bin/echo

Yang, sepertinya menyiratkan bahwa executable di / bin / echo akan dieksekusi (yang tidak akan). Saya menyarankan perubahan dari atmenjadi also found in PATH at:

echo: a regular built-in also found in PATH at /bin/echo

akan membuat deskripsi yang lebih baik. Mungkin menyertakan itu dalam tanda kurung (seperti jawaban yang lain lakukan) bisa membuatnya lebih baik.


Dalam mode POSIX, tidak ada builtin biasa yang akan berfungsi kecuali itu juga ditemukan di PATH.

Namun, keduanya (POSIX) spesial:

break colon continue dot eval exec exit export
readonly return set shift times trap unset

Dan semi-khusus yash (tidak khusus untuk POSIX):

alias bg cd command false fc fg getopts jobs
kill pwd read true umask unalias wait

builtin masih berfungsi.

Ishak
sumber