Saya sangat mengetahui utilitas source
(alias .
), yang akan mengambil konten dari file dan menjalankannya di dalam shell saat ini.
Sekarang, saya mengubah beberapa teks menjadi perintah shell, dan kemudian menjalankannya, sebagai berikut:
$ ls | sed ... | sh
ls
hanyalah contoh acak, teks aslinya bisa apa saja. sed
juga, hanya contoh untuk mengubah teks. Yang menarik adalah sh
. Saya menyalurkan apa pun yang saya punya sh
dan menjalankannya.
Masalah saya adalah, itu berarti memulai sub shell baru. Saya lebih suka menjalankan perintah dalam shell saya saat ini. Seperti yang bisa saya lakukan dengan source some-file
, jika saya memiliki perintah dalam file teks.
Saya tidak ingin membuat file temp karena terasa kotor.
Sebagai alternatif, saya ingin memulai sub shell saya dengan karakteristik yang sama persis dengan shell saya saat ini.
memperbarui
Oke, solusi menggunakan backtick pasti berhasil, tetapi saya sering perlu melakukan ini saat saya memeriksa dan mengubah output, jadi saya lebih suka jika ada cara untuk menyalurkan hasilnya menjadi sesuatu pada akhirnya.
pembaruan menyedihkan
Ah, /dev/stdin
benda itu terlihat sangat cantik, tetapi, dalam kasus yang lebih kompleks, tidak berhasil.
Jadi, saya punya ini:
find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/git mv -f $1 $2.doc/i' | source /dev/stdin
Yang memastikan semua .doc
file memiliki ekstensi yang lebih rendah.
Dan yang kebetulan, bisa ditangani xargs
, tapi bukan itu intinya.
find . -type f -iname '*.doc' | ack -v '\.doc$' | perl -pe 's/^((.*)\.doc)$/$1 $2.doc/i' | xargs -L1 git mv
Jadi, ketika saya menjalankan yang pertama, itu akan langsung keluar, tidak ada yang terjadi.
Jawaban:
$ ls | sed ... | source /dev/stdin
UPDATE: ini bekerja di bash 4.0, serta tcsh, dan dash (jika Anda mengubah
source
ke.
). Rupanya ini buggy di bash 3.2. Dari catatan rilis bash 4.0 :sumber
| bash
akaneval "$(sed ...)"
pendekatan ini - tapi terima kasih atas perhatian 3.2 bug!The
eval
Perintah ada untuk tujuan ini.eval "$( ls | sed... )"
Selengkapnya dari manual bash :
sumber
eval "$( ssh remote-host 'cat ~/.bash_profile' )"
Perhatikan bahwa saya memang menggunakan bash 3.2.Wow, saya tahu ini adalah pertanyaan lama, tetapi saya menemukan diri saya dengan masalah yang persis sama baru-baru ini (begitulah cara saya sampai di sini).
Bagaimanapun - saya tidak suka
source /dev/stdin
jawabannya, tapi saya pikir saya menemukan yang lebih baik. Sebenarnya ini tampak sederhana:echo ls -la | xargs xargs
Bagus kan? Sebenarnya, ini masih tidak melakukan apa yang Anda inginkan, karena jika Anda memiliki banyak baris, itu akan menggabungkannya menjadi satu perintah alih-alih menjalankan setiap perintah secara terpisah. Jadi solusi yang saya temukan adalah:
yang
-L 1
pilihan berarti Anda gunakan (paling) 1 baris per perintah eksekusi. Catatan: jika baris Anda diakhiri dengan spasi, itu akan digabungkan dengan baris berikutnya! Jadi pastikan setiap baris diakhiri dengan non-spasi.Akhirnya, Anda bisa melakukannya
untuk melihat perintah apa yang dijalankan (-t adalah verbose).
Semoga seseorang membaca ini!
sumber
Coba gunakan substitusi proses , yang menggantikan keluaran dari perintah dengan file sementara yang kemudian dapat bersumber:
source <(echo id)
sumber
echo <(echo id)
/dev/fd/12
cat <(echo id)
id
source <(echo id)
id
(...)
dialihkan?Saya yakin ini adalah "jawaban yang benar" untuk pertanyaan:
ls | sed ... | while read line; do $line; done
Artinya, seseorang dapat menyalurkan ke dalam
while
loop; ituread
perintah perintah mengambil satu baris dari yangstdin
dan penerima haknya untuk variabel$line
.$line
kemudian menjadi perintah yang dieksekusi dalam loop; dan itu berlanjut sampai tidak ada baris lagi dalam masukannya.Ini masih tidak akan berfungsi dengan beberapa struktur kontrol (seperti loop lain), tetapi sesuai dengan tagihan dalam kasus ini.
sumber
Saya merasa seperti
ls | sed ... | source -
akan lebih cantik, tapi sayangnyasource
tidak mengerti-
maksudnyastdin
.sumber
Saya rasa solusi Anda adalah penggantian perintah dengan backticks: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html
Lihat bagian 3.4.5
sumber
$( )
sintaksnya mungkin lebih disukai. 'Course backticks bekerja di lebih banyak cangkang ...Untuk menggunakan solusi mark4o pada bash 3.2 (macos), string di sini dapat digunakan sebagai pengganti pipeline seperti dalam contoh ini:
. /dev/stdin <<< "$(grep '^alias' ~/.profile)"
sumber
Mengapa tidak digunakan
source
?$ ls | sed ... > out.sh ; source out.sh
sumber