perlからsystemコマンド呼ばれる時のシェルについて

このQ&Aのポイント
  • HP-UX/perl4のスクリプトをLinux(Red Hat)/perl5に移植する際、system関数でのシステムコマンド実行に問題が発生しています。
  • HP-UXではkshをシェルとして使用し、kshで動作するsystemコマンドを使用していましたが、Linuxではshが使われているため、エラーメッセージが表示されます。
  • ログインシェルをkshに設定しても、perlからsystem関数やバッククォートでシステムコマンドを実行するときにはshが使われるため、問題が発生します。移植先のperl内でシステムコマンドがkshで動くようにする方法を教えてください。
回答を見る
  • ベストアンサー

perlからsystemコマンド呼ばれる時のシェルについて

HP-UX/perl4 で作成したスクリプトを、Linux(Red Hat)/perl5 へ移植するに当たって、system関数の動作が異なり困っています。 HP-UX では ksh をシェルとして使用していたため、perl からのsysytem関数で実行するsystemコマンドも、kshで動作するものを使っていました。Linuxでもログインシェルをkshに設定しました。 ところが、HP-UXで使っていたprintコマンドが使用できず、以下のエラーメッセージが出ます。 sh: print: command not found シェルはkshを指定していても、perlからsystem関数やバッククウォート`` でシステムコマンドを実行するときは、shが使われるようなのです。 perl内の記述は以下のとおりです。 system("print 'a'"); "print"の前に"ksh "をつけたり、"print"を"echo"に変えると、正しく動作します。 移植するperlの本数が多いのと、print以外にもこの問題が起きるかもしれませんので、できれば perl 内からのシステムコマンド実行時にもログインシェルとおなじ ksh で動くようにしたいのですが、どのようにすればよいのでしょうか? よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

perl の system コマンドは、基本的に、プログラムを直接起動します。 リダイレクトなどシェルが必要な構文が使われている場合には、/bin/sh を通しますが、どちらにせよ、ログインシェルである ksh が呼び出されることはありません。 ( system("echo 'a'"); が動作するのは、/bin/sh の内部コマンドとは別に、/bin/echo がインストールされているからです) そのため、ksh の内部コマンドを system 経由で直接利用することはできません。 HP-UX環境では、外部コマンドとしてプログラム「print」がインストールされているのではないでしょうか。(もしくは、/bin/sh が ksh になっているとか) Linux 環境でも、同様動作をする「print」プログラムをインストールすれば、perlスクリプトは改変しなくても動作させられるように出来ると思います。 おそらく --- #!/usr/local/bin/ksh print $* --- といった2行のシェルスクリプトでいけるんじゃないでしょうか。

k_mu_2001
質問者

お礼

分かりやすいご回答、ありがとうございます。 HP-UX で、(/usr/bin/sh print "a")とすると動きましたが、 Linuxでは動きませんでした。 printはパスが通っているところにありませんでしたので、 HP-UXでも外部コマンドとしてインストールされているのではないようでして、おっしゃられるように、/bin/sh が ksh になっているといった理由のようです。 お示しいただいた print プログラムを作ることで、解決できました。 どうもありがとうございました。

関連するQ&A

  • perlスクリプト内でシェルコマンドを実行するには??

    タイトル通りなのですが、perlスクリプト内でシェルコマンドを実行させる方法が分からなく、困っています。 実行したいシェルコマンドはUNIXのcrontab なのですが・・。 また、perlスクリプト内以外でシェルコマンドを実行する方法はあるのでしょうか?? どなたか分かる方いらっしゃいましたらご教授いただけると幸いです。よろしくお願いします。

    • ベストアンサー
    • Perl
  • PERLとシェルについて

    コマンドプロンプトで入力されたPERLコマンドはシェルのプログラムによってカーネルに引き渡されてカーネルがPERLのプログラムにそのコマンドを実行させて、その結果をカーネル→シェルへと引き渡されてコマンドプロンプトに表示されるのでしょうか?

  • system関数でatコマンドを呼び出して使用したいのですが

    はじめまして、system関数について質問があります。 TVキャプチャが動作しているマシンがありまして(OSはFedoraCore6) そこでperlでCGIを作成して、その中で予約録画みたいなことがやり たいのですが、CGI中にsystem関数でatコマンドを利用して予約をして みたのですが、うまく動作しません。 $1 = 10; $2 = 20; system(`echo "xxxx.sh"|at $1:$2`); (xxxx.shはmencoderを起動するシェルスクリプト) みたいにしているのですが、atqなどで確認しても予約されていません。 どのようにしたらsystem関数からatコマンドが利用できるのでしょうか? ご教授よろしくお願いします。

  • shはシェルなのかコマンドなのか?

    http://d.hatena.ne.jp/KishikawaKatsumi/20080504/1209922424 で $ sudo sh j2sdk-1_4_2_13-linux-i586-rpm.bin $ sudo rpm -ivh j2sdk-1_4_2_13-linux-i586.rpm と、shと打ち込むと最後の.binが消えますが、shは シェルなのか、それともコマンドなのかどちらなの でしょうか? 手元にあるlinuxの入門書には「shはシェルの一種である」 と記述があります。googleで検索をしてみましたが、 コマンドであるような記述もあり、混乱しております。 また、その入門書には「シェルを切り替えるには、コマンドライン でシェルの名前を入力します。exitコマンドで、元のシェル に戻ります」とあり、その文章の下には実際にshと打ち込んでexit で元に戻る様が書いてあるので実際に試してみました。 [root@localhost ~]# sh sh-3.2# exit exit [root@localhost ~]# この記述のせいでますますわからなくなりました。 なお、最後のbinがシェルスクリプトであることは理解して おります。 ご存じの方、ご教授頂ければ幸いです。何卒宜しくお願い申し 上げます。

  • Perlで特定のコマンドを実行させるには?

    Perlでコマンドを実行させようと考えておりますが、 Windows版では $ret = ''; $ret = system 'echo', 'test ok!'; で正しく実行されましたが、 Linuxでは $ret = ''; $ret = system '/sbin/service', 'httpd stop'; で、認識できないコマンドとなりエラーになりました。 通常のコマンドラインでは /sbin/service httpd stopは動作します。 Linuxコマンドを実行させたいのですが、何かミスをしているのでしょうか?

    • ベストアンサー
    • Perl
  • シェルの実行中にユーザ切り替えてコマンド実行

    はじめまして。 シェル初心者です。 shell.shをrootユーザでクーロン実行していますが、 shell.shの処理の中で、違うユーザでコマンド実行したいのですが、 可能かどうかも、方法が分かりません。 教えていただけないでしょうか。 環境はLinuxです。 下記のコマンドを実行したいです。 リモートでログインしてコマンド実行結果を取得する ssh -l tomcat server_tomcat grep test /tmp/test.log ※他のユーザでsshを実行してコマンド結果を取得したいです。 以上。宜しくお願い致します。

  • system関数でのシェル起動について

    system関数でシェルコマンドを発行しているC言語のプログラムがあります。 起動されるシェルコマンド(Cシェル)は2重起動防止のため以下の様にコマンド名をgrepしてPIDを取得し、2つ以上あると2重起動と見なしてコマンドを終了させています。 ps -aef | grep 自身のコマンド名 | grep -v grep ~ この時1回目の起動であるのに2重起動チェックに引っかかってしまいコマンドが実行されませんでした。 デバッグしたところ"csh コマンド名"のPIDとは別に一瞬"sh -c コマンド名"というプロセスがあってそれのPIDと合わせて2つに起動していると見なしていました。 調べたところsystem関数はsh経由(sh -c)でコマンドを実行するためだと言う事が分かり納得出来ました。 また元々バックグラウンドで起動させたいコマンドだったので以下の様に"&"を付与したところ2重起動チェックには引っかからなくなりました。 system("コマンド名 &") バックグラウンド起動させても2重起動チェックで弾かれれば納得出来るのですが、通常の起動と何が違うか分からずに釈然としません。 良く分かりませんが、通常起動だとオーバーヘッドで実行に時間がかかりチェックで弾かれるけど、バックグラウンドだと一瞬で起動されてたまたま上手く行った様に見えるだけだったりするなどなのでしょうか?? もしご存知の方がいらっしゃいましたらご教示頂けると幸いです。

  • Kシェルのリダイレクト

    Kシェルのリダイレクト シェル初心者で申し訳ございませんが、ご教授いただけたら幸いです。 やりたいこと  xxx.kshの実行ログを出力したい。 出力したいログは、以下コマンド実行時に標準出力されるログをファイルへ落としたい。 尚、実際の実行コマンドは、ksh -xは入力しません。 $ ksh -x ./xxx.ksh 上記コマンドを実行すると、詳細なログが表示されるのですが、ファイルへ落としたいと思います。 分かりづらいかも知れませんが、宜しくお願い致します。

  • シェルスクリプト コマンドを変数にした時の呼び方

    はじめまして、シェルスクリプトを勉強中の者です。 コマンドを変数にいれて、まとめました。 しかしコマンドの変数を呼びこもうとするとエラーになります。 ============================================ #!/bin/sh GREP="grep" cat "${GREP} '^[0-9]' /home/hoge/test.nicdf" ============================================ ================ シェル実行結果 ============= $ ./test.sh cat: grep '^[0-9]' /home/hoge/test.nicdf: そのようなファイルやディレクトリはありません どう書けば、エラーにならずに正常に動作するでしょうか? ご教授の程よろしくお願いします。

  • [シェルスクリプト内で bashコマンド後のコマンドが実行されない]

    [シェルスクリプト内で bashコマンド後のコマンドが実行されない] 以下の様にシェルスクリプトを記述するとコマンド2が実行されません。 #! /bin/sh コマンド1 bash コマンド2 bash環境でコマンド2を実行させるにはどうしたら良いのでしょうか?