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

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

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

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

SSH

SSH(Secure Shell)は、セキュアチャネルを通してデータを交換するためのネットワークプロトコルです。リモートサーバーへのコマンド実行やファイル転送を行う時に一般的に使用されます。

Linux

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

Mojolicious

Mojoliciousは、Perlで書かれたリアルタイムWebアプリケーションフレームワークです。

Q&A

2回答

6974閲覧

PerlでSSH接続するとエラーが発生する

ester41

総合スコア148

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

SSH

SSH(Secure Shell)は、セキュアチャネルを通してデータを交換するためのネットワークプロトコルです。リモートサーバーへのコマンド実行やファイル転送を行う時に一般的に使用されます。

Linux

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

Mojolicious

Mojoliciousは、Perlで書かれたリアルタイムWebアプリケーションフレームワークです。

0グッド

0クリップ

投稿2016/07/26 06:14

編集2016/07/27 07:05

###前提・実現したいこと
Mojoliciousで開発しているWebアプリから、Net::OpenSSHで別のサーバーへ接続した後、
Net::Telnetで処理を行おうとしています。

開発環境では問題は発生しませんでしたが、
本番環境では環境変数TERMが設定されていないとのエラーが発生します。
本番環境にTeraTermで接続し、下記コードを手動実行すると、エラーなく実行されました。

少ない情報ですが、原因と解決方法がわかる方、よろしくお願いします。

###発生している問題・エラーメッセージ
システムメッセージの出力後に、プロンプトではなくエラーが表示されます。

Last login: Dec SAT 31 23:59:59 2016 from HOGE TERM environment variable not set

###該当のソースコード
Mojoliciousのコードは公開用に書き換えるのが大変な為、手動実行用コードのみとさせてください。
根本部分の流れに変わりはありません。(FWに合わせた記述やエラー処理等が書いてあります。)

Perl

1use Net::OpenSSH; 2use Net::Telnet; 3use utf8; 4my ( $prematch, $match ); 5print "\n\n#################### 処理開始 ####################\n"; 6 7### SSH接続実行 8my $ssh = Net::OpenSSH->new( 9 'CONNECTION_IP_ADDRESS', 10 ( 11 user => 'LOGIN_USER', 12 password => 'LOGIN_PASSWORD', 13 timeout => 5, 14 master_opts => [ -o => 'StrictHostKeyChecking=no' ], 15 default_encoding => 'utf8' 16 ) 17); 18 19### 各種確認 20# TERMの確認 21$prematch = $ssh->capture( { stderr_to_stdout => 1 }, 'echo $TERM' ); 22print "TERM: $prematch\n"; 23 24# envの確認 25$prematch = $ssh->capture( { stderr_to_stdout => 1 }, 'env' ); 26print "ENV: $prematch\n"; 27 28### Net::Telnetに処理委譲 29# PTYの生成 30my ( $pty, $pid ) = $ssh->open2pty( { stderr_to_stdout => 1 } ); 31 32# 処理委譲 33my $prompt = '/\[.*@.*\]\$\s*$/'; 34my $telnet = Net::Telnet->new( ( -fhopen => $pty ) ); 35# 本番環境ではここで 36# TERM environment variable not setエラーが発生 37( $prematch, $match ) = $telnet->waitfor($prompt); 38print "$prematch$match"; 39 40# 適当なコマンドを実行 41$telnet->print('pstree -ah'); 42( $prematch, $match ) = $telnet->waitfor($prompt); 43print "$prematch$match"; 44$telnet->print('ps aux'); 45( $prematch, $match ) = $telnet->waitfor($prompt); 46print "$prematch$match"; 47 48### 切断処理 49# Telnet 50$telnet->print('exit'); 51$telnet->close; 52waitpid( $pid, 0 ); 53# SSH 54$ssh->capture( { stderr_to_stdout => 1 }, 'exit' ); 55$ssh = undef; 56print "\n#################### 処理終了 ####################\n";

実行例

bash

1#################### 処理開始 #################### 2TERM: dumb 3 4ENV: SHELL=/bin/bash 5SSH_CLIENT=127.0.0.1 42171 22 6USER=HOGE 7LS_COLORS= 8MAIL=/var/mail/HOGE 9PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin 10PWD=/HOGE 11LANG=ja_JP.UTF-8 12SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass 13SHLVL=1 14HOME=/HOGE 15LOGNAME=HOGE 16CVS_RSH=ssh 17SSH_CONNECTION=127.0.0.1 42171 127.0.0.1 22 18LESSOPEN=|/usr/bin/lesspipe.sh %s 19G_BROKEN_FILENAMES=1 20_=/bin/env 21 22Last login: Wed Jul 27 15:48:09 2016 from HOGE 23[HOGE@DUMMYHOST ~]$ pstree -ah 24init 25 +-acpid 26~ 中略 ~ 27 +-sshd 28 | +-sshd 29 | | `-sshd 30 | | `-bash 31 | | `-perl 32 | | +-ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=2 -2MNx -o NumberOfPasswordPrompts=1 -o... 33 | | `-ssh -qtt -S /HOGE/.libnet-openssh-perl/HOGE-127.0.0.1-3408-813586 -l HOGE 127.0.0.1 -- 34 | `-sshd 35 | `-sshd 36 | `-bash 37 | `-pstree -ah 38~ 中略 ~ 39 40[HOGE@DUMMYHOST ~]$ 41[HOGE@DUMMYHOST ~]$ ps aux 42USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 43root 1 0.0 0.0 2160 632 ? Ss Jul20 0:00 init [5] 44~ 中略 ~ 45root 3266 0.0 0.0 10060 2852 ? Ss 15:48 0:00 sshd: HOGE [priv 46HOGE 3268 0.1 0.0 10212 1620 ? S 15:48 0:00 sshd: HOGE@pts/0 47HOGE 3269 0.0 0.0 5708 1480 pts/0 Ss 15:48 0:00 -bash 48HOGE 3408 2.2 0.1 11772 7072 pts/0 S+ 15:48 0:00 perl 49HOGE 3411 0.0 0.0 7048 2424 pts/1 Ss+ 15:48 0:00 ssh -o StrictHo 50root 3412 0.0 0.0 10036 2804 ? Ss 15:48 0:00 sshd: HOGE [priv 51HOGE 3414 0.0 0.0 10192 1656 ? S 15:48 0:00 sshd: HOGE@pts/3 52root 3455 0.0 0.0 0 0 ? S Jul20 0:01 [pdflush] 53HOGE 3465 0.0 0.0 6916 2028 pts/2 Ss+ 15:48 0:00 ssh -qtt -S /HO 54HOGE 3466 0.0 0.0 5708 1480 pts/3 Ss 15:48 0:00 -bash 55HOGE 3495 0.0 0.0 5292 940 pts/3 R+ 15:48 0:00 ps aux 56HOGE 7317 0.0 0.2 49828 12324 ? S Jul20 0:00 /usr/libexec/no 57~ 中略 ~ 58 59[HOGE@DUMMYHOST ~]$ 60[HOGE@DUMMYHOST ~]$ 61#################### 処理終了 ####################

###試したこと

  • TERMの確認

手動でもApacheからもdumbとなっていた

  • Telnet処理委譲前に"export TERM=dumb"を実行

TERM未定義エラーとなる

  • Apache.confに"SetEnv TERM dumb"を追記

TERM未定義エラーとなる

  • 開発サーバーと本番サーバーの、Apacheのenvを比較

特別な設定等は差異無し
環境変数の種類も同じ

  • tcpdumpでパケットの確認

パケットが暗号化されているため解析できず

  • 接続先の/etc/ssh/sshd_confを確認

デフォルトコンフィグのと差異無し

###補足情報(言語/FW/ツール等のバージョンなど)

  • Perl,CPANモジュールのバージョン

Perlインストーラー: perlbrew
Perl(5.22.1)
Net::OpenSSH(0.73)
Net::Telnet(3.04)
IO::Pty(1.12)

  • 接続元サーバーのOSとOpenSSHのバージョン

開発サーバー(仮想サーバー): CentOS6.5
本番サーバー(仮想サーバー): CentOS6.5
OpenSSHのバージョン: 5.3p1

  • 接続先サーバーのOSとOpenSSHのバージョン

開発サーバー(仮想サーバー): CentOS5.7
本番サーバー(実サーバー) : RHEL5.7
OpenSSHのバージョン: 4.3p2

導入ライブラリは、各OSのインストールCD付属のもののみ使用しています。
接続先サーバーは、他社保有サーバーでかつ運用中のため、追加パッケージ導入やプロセスの再起動は出来ません。

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

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

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

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

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

SpiceMan

2016/07/28 04:55

MojoliciousをCGIとしてデプロイしていますか
ester41

2016/07/28 05:51

はい、ScriptAliasで、CGIスクリプトとして認識させています
guest

回答2

0

作成されてからだいぶ時間がたっていますので、解決されているかと思いますが、思い当たる点としてコメントさせていただきますね。

ssh接続に関しては、通常 ssh ユーザ名@サーバ名 といった感じでターミナルを使ってログインするケースと、非対話モードでログインして操作するケースとがあります。上記のプログラムは、後者にあたるのではないかと思います。

対話モードの場合は、ログインするアカウントの /.bash_profile (もしくは/etc/bash_profile)の設定を見に行きます。
一方、非対話モードの場合は、
/.bashrc (/etc/bashrc) の方を見に行きます。

環境変数がうまく引き継がれないなあ...という場合は、このあたりも確認してみると良いかと思います。
.bash_profile と .bashrcの違い、で検索するといろいろ出てきますので、お試しください。

もしビンゴであれば、~/.bashrcのほうに export TERM=dumb といった設定をしてあげるとうまくいくのかな...と思います。

投稿2016/09/21 13:23

suama

総合スコア1997

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

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

ester41

2016/09/22 12:02

ご回答ありがとうございます。 実は別方法でこの件は回避したのですが、 (自サーバーに対してTelnet接続を行い、sshコマンドで接続先サーバーへ接続。とても非効率ですね(^_^;)) 気持ちが悪いので時間が空き次第、少しずつLinuxのソースコードを追っていって調べて行っていますがまだ解決できていないです。。。 非対話モードの場合、~/.bashrcを見に行くのは初耳でした。 Net::OpenSSHのコードを読むと、接続すると非対話モードで通信を行い、open2ptyを実行すると対話モードになるみたいです。 bashへ処理が移譲されてからに絞って調査を行いたいと思います。
guest

0

うーん、わからないですねw

基本的にSSHの接続はバッチモードになって、ターミナルを期待するコマンドを実行するとそのエラーが発生します。

例:バッチモードで clear コマンドを実行 ⇒ 画面の文字を消去しようとする ⇒ 画面はない ⇒ エラー

Net::OpenSSH の tty オプションを有効 ( tty => 1 )は解決できるでしょうか

投稿2016/07/28 07:16

SpiceMan

総合スコア12

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

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

ester41

2016/07/28 07:58

ご回答ありがとうございます。 Net::OpenSSHでコマンド発行した際、プロンプト判定がない理由がバッチモードだったからだったのですね。 (バッチモードについて初めて知りました。) 本番環境にアクセスできないので推測となりますが、ttyオプション有効化で解決できなさそうです・・・。 ttyオプションの設定箇所を調査してみました。 new時には設定できず、open_ex等で設定できるみたいです。 PTY生成関数のopen2pty内でopen_exを呼んでおり、 その部分でttyオプションを有効化していました。 ```perl my ($pty, undef, undef, $pid) = $self->open_ex({ stdout_pty => 1, stdin_pty => 1, tty => 1, %opts }, @_) or return (); ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問