Dash setara dengan pengalihan-sendiri hasil skrip

9

Di Bash Anda dapat mengarahkan ulang semua keluaran stdout masa depan dari skrip yang saat ini berjalan . Misalnya dengan skrip ini,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Ini akan berakhir di syslog:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Tapi ini khusus Bash dan eksekutif telanjang dengan pengalihan tampaknya tidak bekerja di Dash.

Syntax error: redirection unexpected

Bagaimana saya bisa membuatnya bekerja di Dash, atau mungkin di kedua shell?

Alex B
sumber
Bisakah Anda mengklarifikasi apa yang sebenarnya Anda butuhkan? Anda dapat mengalihkan dengan >di dash. Saya sadar Anda sepertinya meminta sesuatu yang lain, tetapi saya tidak tahu apa itu.
terdon
@terdon Saya telah memperluas penjelasannya.
Alex B

Jawaban:

6

Anda bisa melakukannya:

{ commands
....
} | logger -t my_awesome_script

Anda dapat melakukannya dengan shell apa pun.

Jika Anda tidak suka tampilannya, mungkin buat skripnya sendiri dalam suatu fungsi.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff
mikeserv
sumber
Baris terakhir itu harus dipertahankan run ${1+"$@"} || do stuffsehingga argumen tetap dipertahankan.
Adam Katz
@ AdamKatz - bagus, execpt ${1+"$@"}tidak melakukan apa-apa "$@" . Lagi pula itu punya masalah lain.
mikeserv
"$@"akan lewat ""ketika tidak ada argumen sementara ${1+"$@"}akan melewati string kosong ketika tidak ada argumen. Ini sangat berarti bagi banyak program, karena mereka mengurai ""sebagai argumen kosong sedangkan string kosong (tidak dikutip) tidak akan ditafsirkan sebagai argumen sama sekali.
Adam Katz
@AdamKatz - shell Bourne yang sangat tua mungkin (dan saya tidak berharap untuk menemukan dashpada sistem seperti itu) , tetapi sebaliknya "$@"unik karena case zero-args tidak menggantikan argumen null untuk shell POSIX.
mikeserv
1
@ AdamKatz - itu sebenarnya bug bahkan di bsh lama dan seharusnya tidak pernah bekerja seperti itu. Itu akhirnya diperbaiki, tetapi saya tidak tahu apakah itu masih perlu dalam Solaris 10, misalnya. Anda benar tentang $ * - tidak menunjukkan sifat expabsion yang sama rapi - keunikannya hanya berkaitan dengan isi variabel dari ekspansi, meskipun itu akan selalu menjadi sesuatu. Menurut pendapat saya "${@+is especially cool $@}" ,. Tapi praktis tidak jauh berbeda dari ${1+”$@"}solusi lama . Jika Anda memiliki ksh93:"${1+quoted" not quoted "quoted again}"
mikeserv
5

Substitusi proses mudah disimulasikan dengan pipa bernama.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

Faktanya, pipa bernama adalah salah satu mekanisme (yang lain /dev/fd) yang dengannya proses substitusi dapat diimplementasikan bash.

chepner
sumber
Yang paling serbaguna menurut saya: Saya bisa menggunakan tee untuk mengarahkan ulang ke beberapa aliran dengan mulus. Hanya satu hal: jangan lupa untuk menghapus logger_input yang dibuat di akhir skrip.
lauhub
2

Saya rasa ini tidak mungkin dilakukan dash. Sejauh yang saya tahu dari manhalamannya , tidak ada dukungan untuk proses substitusi.

Sebagai solusinya, Anda bisa mencoba apa yang disarankan mikserv , atau Anda dapat mengarahkan ulang semuanya ke file, dan kemudian setelah skrip Anda selesai (mungkin ini ada dalam skrip), tambahkan konten file itu ke logger:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script
terdon
sumber
Faktanya, proses substitusi - atau apa yang oleh shell lain disebut sebagai subtitusi proses - lebih mudah dilakukan pada dashshell lainnya. Substitusi proses hanya sejumlah argumen yang menunjuk ke /dev/fd/[num]tautan ke pipa anonim. dashdi sini-dokumen dengan pipa anonim daripada membuat file temp seperti kebanyakan shell lainnya. Jadi cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\ntidak hanya setara secara fungsional, Anda bahkan bisa menamai fd sendiri. Namun, poin Anda dibuat dengan baik tentang pergi ke arah lain - Anda perlu membuka fd baru dengan execdan latar belakang proses yang membacanya.
mikeserv
2
@ mikeserv: Dalam arti apa cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"lebih mudah" daripada cat <(get output)?
ruakh
@ mikeserv: Ini melibatkan banyak aturan untuk diingat; mungkin Anda telah menjadi begitu terbiasa dengan mereka sehingga Anda tidak menyadarinya.
ruakh
@ruakh - yah, tentu. < >pengalihan shell. pada dasarnya jika Anda hanya melakukan dua dari itu Anda kemudian dapat menumpuk di baris berikut juga. Tapi ya, Anda ada benarnya - saya suka di sini docs. Namun, sebanyak hal yang mungkin perlu diingat, lebih mudah ketika mereka bekerja secara universal, saya pikir. Kemudian lagi banyak orang tidak memiliki banyak kegunaan untuk kerang lain dan jadi tidak ada bedanya bagi mereka. Aku tidak ada di antara mereka.
mikeserv
1
@ mikeserv: Tidak hanya heredocs, tetapi juga /dev/fd/3(dalam bentuk yang tepat), dan detail dari apa yang terjadi pada spasi putih. . . dan dalam hal ini, fakta bahwa seluruh pendekatan ini bekerja di Dash, ketika itu tidak bekerja di shell lain yang memiliki semua komponen, berarti bahwa pendekatan keseluruhan adalah aturan khusus yang perlu diingat. (Ini mengingatkan saya pada upaya untuk menciptakan bahasa Inggris yang disederhanakan dengan kosakata yang lebih sedikit; mereka memotong kata-kata seperti bertahan , tetapi mereka mengabaikan idiom yang sama sulitnya seperti terus .)
ruakh