Saya menggunakan server Ubuntu 16.04 dan saya ingin menggunakan utilitas at
dalam sesi saya saat ini untuk melakukan sesuatu 1 menit dari sekarang (katakanlah, an echo
), tanpa memberikan tanggal dan waktu tertentu - hanya 1 menit lebih cepat dari waktu sekarang.
Ini gagal:
echo 'hi' | at 1m
Alasan saya memilih at
lebih sleep
adalah karena sleep cacat sesi saat ini dan karenanya lebih cocok untuk menunda perintah di sesi lain, daripada yang kami bekerja dengan sebagian besar waktu. AFAIR, at
tidak berperilaku seperti ini dan tidak akan mengganggu sesi saya.
Perbarui_1
Dengan jawaban Pied Piper, saya sudah mencoba:
(sleep 1m; echo 'hi') &
Saya memiliki masalah dengan metode ini: Aliran "hi" dicetak di dalam prompt utama saya dan juga menambahkan prompt sekunder kosong ( _
) tepat di bawah prompt utama yang berisi itu, lihat:
USER@:~# (sleep 1m; echo 'hi') &
[1] 22731
USER@:~# hi
^C
[1]+ Done
Perbarui_2
Dengan jawaban Peter Corde saya mencoba:
(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
Ini berfungsi dengan baik di Bash 4.4, tetapi tidak di beberapa versi yang lebih lama, tampaknya (lihat komentar dalam jawabannya). Saya pribadi menggunakan Bash 4.3 di lingkungan saya sendiri.
Jawaban:
Tidak, ini bukan "dicetak di Anda
stdin
".Jika Anda menekan kembali, itu tidak akan mencoba dijalankan
hi
sebagai perintah. Hanya saja latar belakangecho
dicetakhi
saat kursor mengikuti permintaan Anda.Mungkin Anda ingin mencetak baris baru , seperti
(sleep 1m && echo -e '\nhi' &)
. (Sesuaikan seperlunya untukecho
di shell Anda. Atau gunakanprintf
untuk portabilitas.)Saya menempatkan bagian
&
dalam subkulit untuk "menolak" pekerjaan latar belakang, sehingga Anda juga menghindari "suara" dari[1]+ Done
. Dengan di&&
antara perintah,&
berlaku untuk seluruh rantai majemuk-perintah, sehingga kembali ke prompt shell segera daripada menunggu untuksleep
keluar seperti yang Anda dapatkan dengan(sleep 1; echo ... &)
Inilah yang terjadi (dengan penundaan 1 detik):
Bash tidak tahu bahwa
echo
mencetak sesuatu, jadi tidak tahu itu perlu mencetak ulang promptnya atau membersihkan layar. Anda dapat melakukannya secara manual dengancontrol-L
.Anda bisa menulis fungsi shell yang mendapat bash untuk mencetak ulang promptnya setelah
echo
selesai . Hanya melakukanecho "$PS1"
tidak akan mereproduksi karakter yang sudah diketik.kill -WINCH $$
pada sistem saya mendapat bash untuk mencetak ulang baris prompt tanpa membersihkan layar, meninggalkanhi
baris sendiri sebelum prompt. SIGWINCH dikirim secara otomatis ketika WINdow size Mengubah, dan respons bash terhadapnya melakukan apa yang kita inginkan.Mungkin bekerja dengan cangkang lain, tapi saya tidak berusaha membuat 100% portable / POSIX ini. ( Sayangnya, ini hanya bekerja pada bash4.4, bukan bash4.3, atau tergantung pada beberapa pengaturan yang saya tidak sadari )
Anda dapat dengan mudah menyelesaikannya dalam fungsi shell yang membutuhkan argumen sleep dan sebuah pesan.
bash 4.3 tidak mencetak ulang promptnya setelah SIGWINCH, jadi ini tidak berfungsi di sana. Saya telah
shopt -s checkwinsize
mengaktifkan kedua sistem, tetapi hanya bekerja pada sistem Bash 4.4 (Arch Linux).Jika tidak berhasil, Anda dapat mencoba
(sleep 2 && echo -e '\nhi' && echo "$PS1" &)
, yang "berfungsi" jika baris perintah kosong. (Ini juga mengabaikan kemungkinan yangPROMPT_COMMAND
diatur.)Tidak ada cara yang benar-benar bersih untuk mendapatkan output terminal untuk bercampur dengan apa pun yang Anda lakukan di terminal nanti, ketika timer menyala. Jika Anda sedang menggulirkan sesuatu
less
, Anda dapat dengan mudah melewatkannya.Jika Anda mencari sesuatu dengan hasil interaktif, saya sarankan memutar file audio. misalnya dengan pemain command-line like
mpv
(fork of MPlayer2). Atau pilih file video sehingga jendela baru terbuka.Anda mungkin ingin memiliki
echo
xterm / konsole / gnome-terminal baru Anda. Gunakan opsi yang membuat terminal tetap terbuka setelah perintah keluar.sumber
Enter
acara tekan tombol, tepat setelah gema muncul, jadi saya secara otomatis akan dibawa kembali ke prompt utama konsol ?(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
.kill -WINCH $$
melakukan refresh prompt shell yang berjalan di terminal. Itulah inti dari menggunakannya. Menekan enter akan mengirimkan perintah yang diketik sebagian, tetapi WINCH tidak, seperti yang saya tunjukkan. Jika Anda belum mengetik apa pun, maka Anda mendapatkan prompt kosong.rm -rf ~/some/directory
, Enter pada waktu yang salah akan berpotensi berjalanrm -rf ~/
. (Tip keamanan: selesaikan jalur pengetikan lalu kontrol-a dan ubahls
menjadirm -rf
, jadi masukkan jari-jari kapan saja tidak akan merusak hari Anda.)(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
dan setelah gema muncul saya mendapat prompt kosong, hanya setelah memukulEnter
saya kembali ke prompt utama ... Maaf jika saya salah paham dengan Anda, saya cukup baru untuk Bash.screen
sesi (dan hanya melalui SSH) pada sistem Ubuntu yang lebih lama, dan saya mendapatkan perilaku yang Anda jelaskan.Yang benar pada penggunaan adalah
at <timespec>
, di mana<timespec>
spesifikasi waktu. Anda juga dapat menggunakan-f
opsi untuk menentukan file yang berisi perintah untuk dieksekusi. Jika-f
dan tidak ada redirection digunakan, at akan membaca perintah untuk mengeksekusi dari stdin (input standar).Dalam contoh Anda, untuk mengeksekusi "beberapa perintah" (saya memilih "beberapa perintah" untuk menjadi "echo hi" dalam contoh di bawah) satu menit setelah Anda menekan enter (sekarang), yang dimaksudkan
<timespec>
untuk digunakan adalahnow + 1 minute
. Jadi, untuk mendapatkan hasil yang Anda inginkan dengan solusi satu-liner, silakan gunakan perintah di bawah ini:echo 'echo hi' | at now + 1 minute
Ini seharusnya (dan akan dilakukan) untuk menjalankan
echo hi
perintah setelah satu menit. Masalahnya di sini adalah bahwaecho hi
perintah akan dieksekusi oleh perintah at dalam dummy tty dan hasilnya akan dikirim ke kotak surat pengguna (jika dikonfigurasi dengan benar - yang memerlukan penjelasan yang lebih luas tentang cara mengkonfigurasi kotak surat di mesin unix dan bukan bagian dari ruang lingkup pertanyaan ini). Intinya adalah bahwa Anda tidak akan dapat langsung melihat hasilecho hi
di terminal yang sama dengan yang Anda berikan perintah. Alternatif termudah adalah Anda mengarahkannya ke "beberapa file", misalnya:echo 'echo hi > /tmp/at.out' | at now + 1 minute
Dalam contoh di atas, "some file" adalah
/tmp/at.out
dan hasil yang diharapkan adalah bahwa file diat.out
bawah / tmp dibuat setelah satu menit dan contais teks 'hai'.Selain
now + 1 minute
contoh di atas, banyak spesifikasi waktu lainnya dapat digunakan, bahkan beberapa yang kompleks. Perintah at cukup pintar untuk mengartikan yang dapat dibaca oleh manusia seperti contoh di bawah ini:now + 1 day
,13:25
,mid‐night
,noon
, ...Silakan merujuk ke halaman manual di untuk lebih lanjut tentang spesifikasi waktu yang mungkin karena variasi yang mungkin cukup luas dan dapat mencakup tanggal, waktu relatif atau absolut, dll.
sumber
at
secara default mengirimkan output melalui surat, tetapi ini harus dikonfigurasi dengan benar agar berfungsi.at <timespec>
dan bendera yang Anda gunakan dan apakah itu sesuai dengan Ubuntu 16.04 xenial.Jalankan
sleep
dalam subkulit:Catatan: di Linux Anda bisa memberikan argumen untuk tidur dalam hitungan detik atau dengan sufiks s / m / h / d (untuk detik, menit, jam, hari). Pada BSD argumen harus dalam hitungan detik
sumber
stdin
) dan bukan di sayastdout
(seperti akan dengan biasaecho
).(sleep 10s; echo 'hi') & 1>
. Saya sekarang membaca lebih lanjut tentang ini.stdin
danstdout
. Mereka tidak ada hubungannya dengan apa yang tampak di terminal Anda; sebaliknya, Anda harus menafsirkannya sehubungan dengan proses tertentu (pada dasarnya, sebuah program). Input standar ("stdin") untuk suatu proses adalah sumber dari mana proses dapat membaca data, dan output standar proses ("stdout") adalah tujuan di mana ia dapat menulis data. Sumber dan tujuan ini bisa berupa program lain, atau file, atau terminal itu sendiri (barang yang Anda ketikkan masuk ke stdin, dan apa pun yang datang ke stdout ditampilkan).Itu gagal karena Anda mem-pipkan output
echo "hi"
, yang hanyahi
untukat
, tetapiat
mengharapkan input itu dapat dieksekusi oleh shell sistem default (biasanya bash, tetapi kadang-kadang sesuatu yang berbeda tergantung pada sistem).Ini:
akan mencapai apa yang Anda coba lakukan. Ini menggunakan shell konstruksi yang disebut 'di sini dokumen', yang umumnya merupakan cara yang diterima untuk melakukan hal semacam ini (karena menangani beberapa baris lebih baik daripada menggunakan
echo
perintah dan tidak perlu membuat file baru seperti yang Anda perlukan dengancat
), dan menerjemahkan ke padanan yang agak lebih rumit menggunakanecho
:Mungkin perlu dicatat bahwa
at
akan mengirimkan perintah-output apa pun kepada pengguna yang memanggilat
perintah, alih-alih memutar-mutar output ke terminal seperti yang ditunda perintahsleep
dalam subkulit. Secara khusus, ini berarti bahwa kecuali Anda telah melakukan kustomisasi sistem, atau bermaksud membaca spool mail lokal Anda, Anda tidak akan bisa mendapatkan output dari perintah yang dijalankanat
.sumber
syntax error. Last token seen: m Garbled time
. Saya tidak tahu kenapa. Saya menggunakan Ubuntu 16.04, Bash 4.0. Mungkin Anda melakukannya di sistem lain. Bahkan ketika saya mengetikat
tanpa argumen lebih lanjut --- saya masih mendapatkan kesalahan yang sama. Lebih banyak data di sini .at 1m
tidak berfungsi untuk POSIX yang kompatibelat
. Perintahnya adalahat now + 1 minute
at
, saya hanya berasumsi bahwa Anda memiliki versi yang menerima sintaks itu.at 1m
bukan POSIX, tetapi implementasi yang kompatibel dengan POSIXat
bebas untuk menafsirkannya seperti yang mereka inginkan, itu tidak membuatat
implementasi kurang patuh untuk menafsirkannya sebagai makna yang sama dengannow + 1 minute
mengembalikan kesalahan atau makna satu bulan yang lalu . TKI, ituat 1m
kode yang bukan POSIX.Kombinasikan jawaban @Peter Cordes dan jawaban ini /programming/23125527/how-to-return-to-bash-prompt-after-printing-output-from-backgrounded-function/23125687#23125687
Kode di bawah ini dari jawaban yang terakhir, dengan sedikit perubahan milik saya. Kompilasi untuk mengajukan a.out (nama apa pun yang Anda suka)
Kemudian jalankan perintah di bawah ini. (Saya meletakkan a.out di dir / tmp /, Anda mungkin perlu mengubah milik Anda)
atau
BTW,
kill -WINCH $$
bekerja dengan baik untuk saya dengan Bash 4.3 di Gentoo.sumber
Membangun berdasarkan jawaban di atas, Anda dapat memiliki perintah tertanam langsung outputnya ke terminal Anda, seperti:
echo "echo hi >$(tty); kill -WINCH $$" | at now + 1 minute
The
tty
perintah mengembalikan jalur perangkat terminal Anda saat ini, melampirkan dalam$(...)
memiliki pesta melaksanakannya dalam sub-shell, dan perintah kill mengirimkan sinyal ke proses saat ini yang akan memiliki pesta ulang mencetak $ PS1 nya cepat.sumber