Tampaknya ada beberapa ketidakkonsistenan yang tidak dapat saya mengerti tentang shell bash.
Jika saya menjalankan:
ls;date;time
hasil dari tiga pertanyaan ditampilkan secara berurutan.
Namun, pada posisi tanggal dan waktu yang dipertukarkan, pesan kesalahan muncul.
Jadi jika saya mengeksekusi:
ls;time;date
pesan kesalahan mengatakan: bash: syntax error near unexpected token 'date'
.
Adakah yang bisa menjelaskan hal ini?
time;date
vsdate;time
. Ini tampaknya menjadi masalah dengan pipeline inbash
dan char terakhir yang dihasilkan dengantime
output. Hasil yang diuji di emulator terminal berbeda adalah: - [Bash] $ date; time # [OK] $ time; date # [ NotOK ] bash: kesalahan sintaks dekat token tak terduga `date '$ error hanya kesalahan # waktu saja tidak muncul bahwa itu adalah hasil dari tanggal apa pun. - [Csh] $ date; waktu # [OK] $ waktu; tanggal # [OK] - [Tcsh] $ date; waktu # [OK] $ waktu; tanggal # [OK] - [Ksh] $ tanggal; waktu # [ OK] $ waktu; tanggal # [OK]Jawaban:
The
time
perintah dalam pipa Anda bukan/usr/bin/time
biner, tetapi bashtime
built-in. Bandingkanman time
denganhelp time
. Kesalahan yang Anda lihat adalah bash gagal menguraikantime
argumen. Ini harus ada atau menjadi baris baru. Ini adalah baris baru dalam contoh pertama Anda tetapi tidak ada di baris kedua.Di sisi lain, jika Anda lari
atau
di mana kutipan sekitar
'time'
mencabut statusnya sebagai kata yang dilindungi undang-undang, maka bash tidak memiliki masalah untuk menguraikan baris. Sekarang mem-parsing tiga perintah dalam daftar, yang akan dieksekusi secara berurutan, dan/usr/bin/time
akan melaporkan kesalahan penggunaan dalam kedua kasus.Tambahan
Diamati bahwa meskipun
time ; date
menghasilkan kesalahan,time ; ; date
tidak. Penjelasan yang mungkin adalah bahwatime ;
ditafsirkan oleh bash setara dengantime <newline>
. Ekspresitime ; ; date
ini kemudian diuraikan sebagai daftartime ;
dandate
.Ini konsisten dengan pengamatan yang
time ;
dantime ; ;
juga legal, yang kedua diuraikan sebagai daftar tunggal yangtime ;
diikuti oleh tanda titik koma yang diizinkan setelah daftar.Jadi cara lain untuk menjelaskan mengapa
time ; date
menghasilkan kesalahanbash: syntax error near unexpected token 'date'
adalah bahwatime
mengkonsumsi titik koma yang memisahkannyadate
. Itu hanya dapat melakukan itu karenatime
ini adalah kata yang dilindungi undang-undang.sumber
time
seharusnya mengizinkan perintah NULL, dan tanda titik koma membatasi daftar, jadi IMOtime
perintah tidak boleh "mengkonsumsi" tanda titik koma setelahnya. Perintah bawaan lainnya (yang dapat mengambil argumen) tidak menunjukkan perilaku semacam ini.time;date
memang salah secara sintaksis dalam penafsiran apa pun. Namuntime ;
dantime ; ;
juga ilegal. Hal ini dapat diperdebatkan apakahtime
perilaku 's adalah bug atau hanya tidak tercatat (itu adalah internal konsisten), namun laporan bug pasti akan berada di tempat. Apakah Anda bersedia untuk mengajukannya?time by itself can time a null command
dan kemudian ia melakukannya$$ = make_simple_command (x, (COMMAND *)NULL);
. Adapun pengajuan bug saya tidak yakin 8)time ; date
pekerjaanksh93
danmksh
tanpa kesalahan, meskipunksh
adatime
kata kunci.Bash memperlakukan built-in
time
sebagai kasus khusus, saat mem-parsing baris perintah.Seperti yang dapat dibaca di bash manpage, baris yang diketik pertama-tama dibagi menjadi daftar:
di mana sebuah pipa adalah:
atau dalam kasus kami, cukup:
yaitu jika waktu hadir, maka perintah harus juga hadir.
[Ada kasus khusus yang memungkinkan
time
untuk diikuti oleh baris baru, tetapi itu tidak berlaku di sini]Jadi, dalam kasus kami, kami memiliki:
dipecah menjadi dua jalur pipa:
dan pipa 1 tidak terbentuk dengan baik, karena kita punya
time
tanpa perintah. Karena itu kesalahannya.Perhatikan bahwa baris perintah
time
juga tidak berfungsi di sini:bash mem-parsing ini seperti yang diharapkan, ke dalam 2 jalur pipa:
dan
/usr/bin/time
kemudian menolak untuk berjalan tanpa argumen. Perhatikan bahwa ini adalah kesalahan/usr/bin/time
bukan kesalahan dari bash.Alasan bahwa back-tick berfungsi adalah bahwa back-tick berhenti
time
ditafsirkan sebagai elemen khusus dalam pipa.yaitu dengan back-tick:
itu diurai sebagai dua pipa:
Ingatlah bahwa saluran pipa, dalam kasus kami, adalah:
dan masalahnya pada awalnya adalah bahwa kami memiliki
time
tanpa perintah, yang tidak diizinkan. Tetapi sekarang kita hanya memiliki perintah:tanpa sebelumnya
time
, karena back-ticks berartitime
ditafsirkan sebagai perintah, bukan sebagai kata sebelumnya.Jadi bash kemudian menjalankan builtin-nya
time
tanpa argumen, yang diterima. Tidak menghasilkan output, dan kami tidak melihat kesalahan.Perhatikan bahwa:
sebenarnya menjalankan hasil dari
time
built-in, yaitu menjalankan apa pun yangtime
dihasilkan built-in pada stdout. Tetapi karenatime
dengan sendirinya tidak menulis apa pun untuk stdout, tampaknya bekerja.Akhirnya, telah dicatat bahwa ini bekerja:
yang saya tidak bisa jelaskan, sayangnya :)
sumber
;date
memberibash: syntax error near unexpected token ;
, tetapitime ;date
memberibash: syntax error near unexpected token date
, jadi sepertinya bash tidak memperlakukan perintah setelah waktu yang dibangun sebagai "; date". Menariknya,time ; ; date
bekerja.'time'
itu kehilangan artinya sebagai kata yang dilindungi undang-undang. Backticking membuatnya dieksekusi dalam subkulit yang outputnya akan disambungkan ke perintah. Ini tidak ada hubungannya dengan diskusi. Faktanya, contoh Anda`time\';date
membuktikan kebalikan dari klaim Anda: ini harus memberikan kesalahan dengan alasan Anda karena/usr/bin/time
memerlukan argumen. Alasannya tidak adalah karena dalam subshell di mana ia mengeksekusi itu adalah kata yang dipesantime
sekali lagi.