質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

2899閲覧

ssh接続 scp

coko1

総合スコア276

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2016/11/04 08:23

編集2016/11/04 08:27

現在ssh接続をして接続先でtxtファイルを作成するシェルスクリプトを組んでいて、
作成したファイルをローカル側にダウンロード(転送,コピー)させるためにssh接続での処理を終えた後に、scpで再度接続して作成したファイルを持ってくるような処理になっています。

簡単な記述例
ssh user@host "commnd" ← ファイル作成
scp コピー元 コピー先 ← 作成ファイルローカルへコピー

何が問題かというと接続方法がパスワード認証方式のためsshとscpで二度パスワードをもとめられることです。なのでssh接続中に作成ファイルをローカルに送る方法はありませんか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2016/11/04 08:47

「 作成したファイル名の情報をどう取得すればいいのかがわからなくて詰まっていて... 」 ファイル名が不明だが、そのファイル名でローカル側にファイルを作りたいと言うことですか?
coko1

2016/11/04 08:56

そういうことです。作成されるファイルが実行日時で名づけられるものなので...
guest

回答2

0

ベストアンサー

リモート側ではメッセージを標準出力でなく標準エラー出力に出して、標準出力にはファイルだけを出します。
また、ファイル名付きで送るために、tar を使います。

Bash

1if [ -e ./$file_name.txt ]; then 2echo >&2 -n “同名のファイルが既に存在します。上書きしてもよろしいですか?[yes/no]3read answer 4if [ "$answer" != "yes" ]; then 5echo >&2 "上書きを行いません" 6exit 7fi 8else 9echo >&2 "新規作成" 10fi 11 12echo >&2 "開始" 13 14----- 15ファイル作成 16----- 17 18echo >&2 "終了" 19tar cf - ./保存ファイル名

ローカル側は、標準出力をtarで受けます。

Bash

1ssh user@host "リモートスクリプト名" | tar xf -

投稿2016/11/04 12:32

otn

総合スコア84533

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coko1

2016/11/05 12:16

申し訳ありません今手元に試す環境がない状態で検証ができないのですがtarコマンドというのがどういうものか教えていただいてもよろしいでしょうか?アーカイブの作成??のような説明は見たのですがよくわからなくて
otn

2016/11/05 12:40 編集

こちらで、 https://ja.wikipedia.org/wiki/Tar アーカイブの時に、ファイル名も含めて記録されます。それをローカルで展開します。
coko1

2016/11/07 00:31

tar: これは tar アーカイブではないようです tar: 次のヘッダをスキップします tar: 前のエラーにより失敗ステータスで終了します 時間が空いてしまい申し訳ありません。 上記のようなエラーが出てしまいました。どうしたらよいでしょうか?
otn

2016/11/07 02:27

標準出力にtar以外の物が出力されています。 どこかに間違いがありますので、よく見てください。
guest

0

ローカルに持ってきたいファイルがテキスト形式なら、sshでcatしてローカルにリダイレクトしてはどうでしょうか?
バイナリの場合はちょっと思いつかないですが...

###2016/11/5 12:00編集

**main.sh** #!/bin/bash REMOTEFILE=`ssh user@host test.sh` ssh user@host "cat ${REMOTEFILE}" > 【適当な書き出し先】
**test.sh** #/bin/bash if [ -e ${FILENAME} ]; then echo >&2 -n "同名のファイルが既に存在します。上書きしてもよろしいですか?[yes/no]" read answer if [ "$answer" != "yes" ]; then echo >&2 "上書きを行いません" exit fi else echo >&2 "新規作成" fi echo >&2 "開始" find ... | awk ... > ${FILENAME} echo >&2 "終了" echo ${FILENAME}

投稿2016/11/04 08:29

編集2016/11/05 03:02
ynakano

総合スコア1894

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coko1

2016/11/04 08:43

テキストファイルです! 実はsshでの接続先でファイルを作成するシェルスクリプトを実行していて、そこで作成したファイルをローカルに持ってくるという話なのですが、作成したファイル名の情報をどう取得すればいいのかがわからなくて詰まっていて...
otn

2016/11/04 08:43

バイナリでもそれで問題ないと思います。元々何も出力がないことが前提ですが。
ynakano

2016/11/04 08:48

「sshでの接続先でファイルを作成するシェルスクリプト」という事であれば、作成するファイル名を変数化して、同じシェルスクリプトでそのファイルをcatしてあげればいい気がします。 (何だか冗長な感じもしますが) >otn様 ご指摘ありがとうございます。 そういえば音声ファイルをcatして音声出力デバイス(スピーカーなど)にリダイレクトして音を鳴らす、みたいな事をやった記憶が蘇ってきました。
coko1

2016/11/04 09:05

解釈はそれで問題ないのですが、ファイルを作成する.shではechoで"新規作成","終了"等を表示させていて、作成したファイルをcat→ローカルでリダイレクトとしてもその”新規作成”などが含まれて書き込まれてしまいます。どうしたらよいでしょうか?
ynakano

2016/11/04 09:12

ちょっと実装のイメージが湧かない部分もあるので、差し支えなければ作成したシェルスクリプトを追記いただければと思います。 その方が後々齟齬が出ないかと。
coko1

2016/11/04 09:18

一部分でよければ。 f [ -e ./$file_name.txt ]; then echo -n “同名のファイルが既に存在します。上書きしてもよろしいですか?[yes/no]” read answer if [ "$answer" != "yes" ]; then echo "上書きを行いません" exit fi else echo "新規作成" fi echo "開始" ----- ファイル作成 ----- echo "終了" cat 保存ファイル名 といった感じです。リダイレクトするとechoの表示も含めてしまう状態です。
ynakano

2016/11/04 09:30

肝心の「ファイル作成」の部分はどんな感じですか? $file_name.txt をそのまま利用できない理由があると言うことでしょうか?
coko1

2016/11/04 09:36

ファイル作成の部分はfindの結果をテキストに書き込んでいるだけになります。(sedなりawkなりで出力を形式は変えています)
ynakano

2016/11/04 10:05

なるほど。 私のイメージだと、ファイル作成の部分が以下のような感じで、 ssh user@host "findなんちゃら > ${REMOTEFILE}" それをローカルに取ってくるのが以下のような感じ ssh user@host "cat ${REMOTEFILE}" > ${LOCALFILE} だと思っていました。 ※もちろん${REMOTEFILE}=${LOCALFILE}でもOKですが。 あと一つ気になったのが、"$file_name.txt"はローカル側のファイルなんですか? リモートファイルの存在チェックだとしたら、以前のcoko1さんご自身の質問で回答させてもらいました。 https://teratail.com/questions/53185 話、噛み合ってますでしょうか?
coko1

2016/11/04 10:18 編集

$file_name.txtはリモートで動かすファイル作成のシェルで作られるものです。 ssh user@host "test.sh(ファイル作成シェル)" がローカルでの処理です。
coko1

2016/11/04 10:53

リモートファイルの存在チェックというより作成したファイル名を取得する方法がわからないという話でして
ynakano

2016/11/04 11:39

前提がちょっと分からないところがあって済みませんね。 唐突にtest.shが出てきたのですが、findとかawkはこの中でやると言うことでしょうか。 お聞きした範囲での想定コードを書きますが、読みづらいので回答に追記します。
coko1

2016/11/04 11:56

まずローカルでssh接続する.shの実行。ssh接続したのちに実行されるのが話にずっと出ているテキストファイルを作成する.shです。接続するための.shと接続先にあらかじめおいてあるファイル作成の.shのふたつがまずあるんです。 なので、ynakanoさんの質問の通りtest.shでfindとかawkを行ってファイルを作成しています。
ynakano

2016/11/04 12:13

確認しますね。 ・出てくるシェルスクリプトは2本。 ・ローカルで動かすもの。仮にmain.shとします。 ・リモートに置いてあるもの。test.sh。findやawkを実行してファイルを作成する。 ・main.shの中でsshでtest.shをキックする。 認識合ってます?
ynakano

2016/11/04 12:16

五月雨式に済みません。 リモートに作成するファイル名はtest.shの中で決めなくてはいけない、つまりmain.shから与えるのは不可、という縛りはありますか?
coko1

2016/11/04 13:22

その認識で問題ないと思います。 そうですね。test.sh内でファイル名を構築しているので...mainから与えるのを想定していないですね。
ynakano

2016/11/04 13:54

スクリプトを直してみました。回答の方を見てみてください。 リモートのtest.shで出力したファイル名を、呼び出し元のmain.shで拾っています。
coko1

2016/11/05 01:47

回答を見させていただいた感じまだ誤解がありそうなので確認させてください。 まずmain.shにecho"新規作成"のような処理はありません。それらの処理は全てtest.shで記述されているものです。この認識をされてますでしょうか? --------- main.sh --------- ssh user@host "commnd"  ←接続後ファイル作成のshを実行 scp コピー元 コピー先 ---------- mainはこの処理のみになります。ssh接続先で作成したファイルをssh接続中でコピーしてくる方法はないのか?また、scpでやる場合にもコピー元のファイル名を指定しなければならないが、ssh接続中にファイル作成shを実行して作成したファイル名をどう取得したらよいかわからない。というのが質問の趣旨になります。 -------- test,sh -------- if [ -e ${FILENAME} ]; then echo -n "同名のファイルが既に存在します。上書きしてもよろしいですか?[yes/no]" read answer if [ "$answer" != "yes" ]; then echo "上書きを行いません" exit fi else echo "新規作成" fi echo "開始" find ... | awk ... > $FILENAME.txt echo "終了" これがtest.shの大体の内容になります
ynakano

2016/11/05 03:09

最初の質問文のスクリプト全体がリモートで実行されるものだったのですね。 根本的に勘違いをしてました。 回答の方にシェルスクリプトを記載しました。 otnさんの回答をパクッた感じになってしまったのですが、test.shで処理するもののうち、画面にだけ出させたい部分は標準エラー出力として、標準出力でファイル名を出力しています。 それを呼び出し元のmain.shで受取るやり方です。 otnさんとの違いはファイル名をやり取りしているという事ですが、ローカル側でファイル名を取得したいという要件があるものと仮定してです。
coko1

2016/11/05 12:20

申し訳ないですが現在検証できる環境がないので確かめることができません。一応ファイル名に関してはtest.shで意味のある名前で作成しているので、その名前のファイルと内容が欲しい感じです。
ynakano

2016/11/05 12:28

「test.shで意味のある名前」というのは"$file_name.txt"の部分でしょうか。 私の書いたtest.shでは、${FILENAME}で置き換えてしまっているのでその部分を読み替えていただければと思います。 一方、呼び出し元のmain.shでは変数${REMOTEFILE}にtest.shで決めたファイル名が格納されます。 そしてそれをssh経由でcatしているので、内容も取得できます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問