Bagaimana cara menjalankan perintah jarak jauh dan mengirimkan file lokal sebagai input?


22

Apakah mungkin untuk melakukan ini:

ssh user@socket command /path/to/file/on/local/machine

Artinya, saya ingin menjalankan perintah jarak jauh menggunakan file lokal dalam satu langkah, tanpa terlebih dahulu menggunakan scpuntuk menyalin file.


Mungkin saja jika komputer jauh memiliki jaringan mount direktori induk dari file mesin lokal atau jika Anda mengarahkan file ke perintah ssh
h3rrmiller

Jawaban:


23

Anda melewatkan satu simbol =)

ssh user@socket command < /path/to/file/on/local/machine

Tentu saja! Saya heran mengapa saya tidak mempertimbangkan pengalihan input lebih dari ssh ?!
jsj

Bagaimana jika perintah jarak jauh hanya dapat mengambil argumen file dan tidak membaca dari stdin?
iruvar

@ChandraRavoori dalam hal ini Anda harus menyalinnya scpsebelumnya.
buru

4
@ChandraRavoori Anda dapat mencoba memberikan argumen file /dev/stdinatau -. Mungkin atau mungkin tidak berfungsi ( /dev/stdinadalah file, tetapi mencarinya akan gagal)
derobert

1
@derobert dan buru-buru, bermain-main dengannya sedikit dan menemukan cara hacky untuk melakukannya menggunakan proses substitusi di bawah bash. Ini masih tunduk pada batasan pencarian dan dapat menjadi sulit dengan semua kutipan tambahan yang akan dibutuhkan. Contoh berikut. cat test.file | ssh user @ machine 'bash -c "wc -l <(cat -)"'
iruvar

4

Salah satu cara yang berfungsi terlepas dari perintah adalah membuat file tersedia di mesin jarak jauh melalui sistem file jarak jauh. Karena Anda memiliki koneksi SSH:

  1. Buat terowongan SSH terbalik . Lihat juga SSH dengan mudah menyalin file ke sistem lokal
  2. Pasang pohon direktori mesin Anda yang berisi file untuk dibagikan di mesin jarak jauh dengan SSHFS . ( Contoh )

Bagaimanapun cara ini membutuhkan gerakan tambahan sebelum eksekusi perintah.
buru

@Gilles: Saya pikir judul aslinya menyesatkan, dan Anda mengerti pertanyaannya berdasarkan judul menyesatkan. Sejauh yang saya tahu, pikir, dia sebenarnya tidak ingin bertindak pada file lokal, tetapi hanya meneruskannya sebagai input. (Tapi jawaban Anda luar biasa, jika saya memahaminya dengan benar! Mungkin saya harus mengajukan pertanyaan yang Anda jawab, hanya untuk memberi Anda tempat untuk meletakkan jawaban di mana Anda akan mendapatkan kredit yang layak untuk itu.) Saya telah mengedit judul pertanyaan untuk membuatnya konsisten dengan tubuh dan dengan jawaban yang dipilih.
iconoclast

@iconoclast Saya tidak ingat keadaan pikiran saya ketika saya menulis ini, tetapi saya mengikuti jawaban ini. Ini memerlukan beberapa pengaturan tetapi memiliki keuntungan generalisasi di luar persyaratan langsung untuk kasus-kasus lain di mana tidak cukup untuk menyalin input. Saya juga sudah menyebutkan pengalihan jika orang lain tidak melakukannya. Pertanyaan yang lebih umum telah ditanyakan berkali-kali dalam bentuk yang sedikit berbeda.
Gilles 'SO- berhenti menjadi jahat'

Oke, saya pasti salah mengerti jawaban Anda. Saya tidak mencobanya, tetapi menyimpulkan bahwa karena Anda membuat terowongan terbalik (dari remote ke host lokal?), Anda mengizinkan file lokal untuk dimodifikasi oleh mesin jarak jauh. Apakah bukan ini masalahnya?
iconoclast

@iconoclast Ya, ini memungkinkan mesin jarak jauh untuk memodifikasi file lokal (selain memungkinkannya untuk membacanya, yang merupakan pertanyaan yang diperlukan).
Gilles 'SANGAT berhenti menjadi jahat'

1
# What if remote command can only take a file argument and not read from stdin? (1_CR)
ssh user@socket command < /path/to/file/on/local/machine
...
cat test.file | ssh user@machine 'bash -c "wc -l <(cat -)"'  # 1_CR

Sebagai alternatif untuk bashmemproses substitusi <(cat -)atau < <(xargs -0 -n 1000 cat)(lihat di bawah), Anda cukup menggunakan xargsdan catmenyalurkan konten file yang ditentukan wc -l(yang lebih portabel).

# Assuming that test.file contains file paths each delimited by an ASCII NUL character \0
# and that we are to count all those lines in all those files (provided by test.file).

#find . -type f -print0 > test.file
# test with repeated line count of ~/.bash_history file
for n in {1..1000}; do printf '%s\000' "${HOME}/.bash_history"; done > test.file

# xargs & cat
ssh localhost 'export LC_ALL=C; xargs -0 -n 1000 cat | wc -l' <test.file

# Bash process substitution
cat test.file | ssh localhost 'bash -c "export LC_ALL=C; wc -l < <(xargs -0 -n 1000 cat)"'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.