以下のスクリプトでLINUX環境でevalが使用できない場合、
input_logを環境変数から取得したいのですが、
何か方法がありますでしょうか?教えてください。


while [ $i -lt 3 ]
do

i=`expr $i + 1`
#入力ファイル名の設定
input_log=log_$i
input_log=`eval echo $"$input_log"`

done

このQ&Aに関連する最新のQ&A

bash とは」に関するQ&A: poor-bashとは?

A 回答 (2件)

#1です。


なるほど。linuxにはevalが無いと思ったんですね。evalはシェルの組み込みコマンドなので、man sh か man bash です。

linuxとFreeBSDでお書きのものを実行して見ました。
・FreeBSDのsh →OK (log_1等の中身がセットされる)
・FreeBSDのbash → NG (log_1等の名前がセットされる)
・linuxのbash → NG (同上)
・linuxのsh → NG (同上)
OSの違いではなく、shとbashのシェルの違いですね。linuxではshは実はbashなので(ls -l `which sh` `which bash` でわかります)、同じ結果ですが。

` ` の中でevalを使うなら、$をクォートすることが必要です。
input_log=`eval echo '$'"$input_log"` または
input_log=`eval echo \\$"$input_log"`
でshでもbashでも上手く行きました。ただ、#1に書いた方法のようにevalは直接使うのが普通だと思います。
    • good
    • 0

evalを使わないやり方の前に、まずこれ動かなくないですか?$log_1,$log_2,$log_3の値を順に参照するという配列相当のことをしたいんですよね?


eval input_log=\$log_$i
では?
evalを使用しないという制約の理由がわかりませんが、
echo echo \$log_$i > tmp.sh
input_log=`sh tmp.sh`
でしょうか。
スクリプトの意図が違う場合は補足ください。

この回答への補足

回答ありがとうございます。

>配列相当のことをしたいんですよね?

はい、そうです。

>eval input_log=\$log_$i
>では?

こちらの方がシンプルですね。試してみます。

>evalを使用しないという制約の理由がわかりませんが、
これはUNIX環境では、動作したのですが、RedHat環境では動きませんでした。(マニュアルでman evalで出てきませんでした。)

>echo echo \$log_$i > tmp.sh
>input_log=`sh tmp.sh`
>でしょうか。
こちらも試してみたいと思いますが、
tmp.shを作成しない方法はないでしょうか?

以上よろしくお願いします。

補足日時:2005/04/24 07:02
    • good
    • 0

このQ&Aに関連する人気のQ&A

bash とは」に関するQ&A: 登校拒否について

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q[UNIXコマンド] eval教えて下さい。

evalって、結局なんのためにあって、どのように使うと便利なのか良く分かりませんでした。(一応manでは見てみましたが・・・)

たしか見た例では
eval `$path -uniq`
ってあったと思います。
あわせて説明して頂けるとさいわです。

Aベストアンサー

仕様の違うシェルはあまりないと思いますが、一般的なシェルでは
eval echo $"$baz"
のevalを省略すると、
echo $"PATH"
の意味になり
$PATH
という文字列が表示されるだけで、PATH変数の内容は表示されません。
ぜひためしてみてください。

Qsqlplusの操作をシェル上で

RedhatLinuxのシェルスクリプト上で
Oracleのsqlplus操作を行うことは可能でしょうか?
その場合、どのように記述すればよいでしょう?

やりたい内容の例としては以下になります。

#!/bin/sh
su -<oracleユーザー>
sqlplus ※※※※
SQL> update ※※※ set ※※※
SQL> exit

上のような内容をcronに登録して自動処理をかけたいと考えています。

Aベストアンサー

シェルスクリプトファイル以外のファイルを作成したくない場合はyjousさんのようにヒアドキュメントを使用するのがいいと思います。
もし、sqlを記述したファイルを置いてもかまわないのであれば
sqlplus ユーザ/パスワード @sqlファイル名
をシェルスクリプト内で書けばいいと思います。
(ファイル名はフルパスで。ファイルの最後にexitを忘れずに。)

シェルスクリプト内でsuでoracleユーザにしていますが、それならcronの登録で

0 * * * * su - oracle -c "シェルスクリプトファイル"
のようにoracleユーザにして実行してみたらどうでしょうか?(oracleはoracleユーザーとしてみてください)

Qgrepで検索文字列が完全一致した行だけ取り出す方法

grepの文字列検索で検索文字列が単語として、完全一致した行だけ取り出す方法はないでしょうか?

通常は
grep hoge hoge.txt

と打つと、hogeが含まれる行が出力されますが、今回は含まれる行ではなくて完全に文字列が一致した行だけ取り出したいのです。

例えばhoge.txtの中に
cc ghoge
kkl hogem
jjll hoge
という3行があったとしたら最後の行でhogeという文字が空白で区切られた行だけ取り出したいのです。

何かよい方法があれば教えてください

Aベストアンサー

-w オプションじゃだめですか?

参考URL:http://www.linux.or.jp/JM/html/GNU_grep/man1/grep.1.html

Qシェルスクリプトでファイル内の数値文字列を数値として扱うには

失礼します。
シェルスクリプトでファイル内のテキスト(数値文字列)を取得して、それを使って計算するにはどうすれば良いでしょうか?

str:ファイル内のテキスト(数値文字列)

res=$(( $str + 1 ))

・エラー
")syntax error: invalid arithmetic operator (error token is "


よろしくお願いします。

Aベストアンサー

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをexprに書き換えたところ
$ ./test2.sh
Using expr
09:19:00.302748000
09:19:19.259990000

exprだと19秒ですが、$(( 演算 )) だと10秒程度なので、演算が多くなれば確かにexprは不利ですね。

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをe...続きを読む

Qシェルスクリプトの実行、「source」と「.」の違いについて

bashのシェルスクリプトを書いています。
当方、Mac Snow Leopard を使っているため、seq コマンドがデフォルトでは使えません。
そこで、.bashrc 内に、seq 関数をあらかじめ自分で定義して、他で使い回したいと思っています。
.bashrc の中に、
function seq() {
i=$1
while [ $i -le $2 ] ; do
echo $i
let i=$i+1
done
}
と、関数を定義しました。
seq 関数をターミナル上で実行すると、
>seq 0 2
0
1
2
と正しく、表示されます。次に、

#!/bin/sh
seq 0 2

と記述したシェルスクリプト(temp.sh)を「source」で実行すると、
>source temp.sh
0
1
2
と正しく、表示されますが、「.」で実行すると、
>./temp.sh
./temp.sh: line 2: seq: command not found
と言われます。
どのような理由によってこの違いが出るのでしょうか??

bashのシェルスクリプトを書いています。
当方、Mac Snow Leopard を使っているため、seq コマンドがデフォルトでは使えません。
そこで、.bashrc 内に、seq 関数をあらかじめ自分で定義して、他で使い回したいと思っています。
.bashrc の中に、
function seq() {
i=$1
while [ $i -le $2 ] ; do
echo $i
let i=$i+1
done
}
と、関数を定義しました。
seq 関数をターミナル上で実行すると、
>seq 0 2
0
1
2
と正しく、表示されます。次に、

#!/bin/sh
seq 0 2

...続きを読む

Aベストアンサー

追記

source は現在のシェルで実行し、結果がそのまま現在のシェルに適応されます。
今回の temp.sh なら
> source temp.sh

> seq 0 2
と入力したのと同等ということになります。

> ./temp.sh
この . はコマンドではなく、 temp.shへのパスを指定するものです。
実行ファイル名だけでコマンドとして実行できるのは、環境変数PATHで指定したディレクトリにあるものだけです。それ以外は、その実行ファイルへの絶対パス、または相対パスが必要となります。
これは、カレントディレクトリにある実行ファイルも例外ではありません。
環境変数PATHに . が無い場合は、 ./ファイル名 と相対パスを指定する必要があります。
(この点は、常に . がPATHにあるように振る舞うMS-DOSやコマンドプロンプトとは違います)
逆に、PATH上にあれば(例えば、 PATH=$HOME/bin:(以下略)となっている時の $HOME/bin )、 temp.sh とファイル名だけで実行できます。

また、こうしたコマンドは新規プロセスで実行されますので、環境変数を除いて、現在の設定は継承されません。
対話的ではないbashや、 shとして起動された bash は .bashrcを読まないので、そこに書いてあることは無効となります。

追記

source は現在のシェルで実行し、結果がそのまま現在のシェルに適応されます。
今回の temp.sh なら
> source temp.sh

> seq 0 2
と入力したのと同等ということになります。

> ./temp.sh
この . はコマンドではなく、 temp.shへのパスを指定するものです。
実行ファイル名だけでコマンドとして実行できるのは、環境変数PATHで指定したディレクトリにあるものだけです。それ以外は、その実行ファイルへの絶対パス、または相対パスが必要となります。
これは、カレントディレクトリにある実行...続きを読む

Qsqlplusで表示が変なので、出力を整形したい。

いつもお世話になっています。

サーバにアクセスしてsqlplusで、
データを調べたいのですが、
出力形式が見づらくて困っています。

よくわからいのですが、
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------
1の値 2の値
3の値
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------

上記のように意味不明な形式で出てきます。

例えばこんな風に

select カラム1,カラム2,カラム3 from hoge;

カラム1 1の値
---------------------------
カラム2 2の値
---------------------------
カラム3 3の値

等のように分かりやすく表示できないでしょうか?

ちなみにOracle9iR2を使用しています。
sqlに関するツールは使用できないルールでして、あくまでsqlplusのコマンド上でみやすくしなければなりません。

分かりづらくですいませんが、皆さま、ご教授お願いします。

いつもお世話になっています。

サーバにアクセスしてsqlplusで、
データを調べたいのですが、
出力形式が見づらくて困っています。

よくわからいのですが、
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------
1の値 2の値
3の値
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
-----------------------...続きを読む

Aベストアンサー

SQLPLUSを起動して、

SQL>set linesize 列数

でどうだ。

SQL>show linesize

で確認ができる。

Qbashなどのシェル変数の値に改行を含める事は可能でしょうか?

タイトルの通りですが、通常のシェル変数の値として

 [prompt]$ aaa="bbb<改行>ccc"

のようなセットを行い、

 [prompt]$ echo $aaa
 bbb
 ccc
 [prompt]$

のような結果を得たいのですが、可能でしょうか。

Aベストアンサー

可能です.
というか,やってみたら出来ることがわかると思います.こんなところで聞くより早い.
なお,sh/bash系では改行文字は特にエスケープせずそのまま入れられます.

aaa='bbb
ccc'

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Qシェルでsyntax errorがでてしまう

温度管理をするため、CentOS4.4上で下記のようなスクリプトを動かしています。

---スクリプト始まり---
#!/bin/bash
date=$(date '+%Y/%m/%d(%a)/%R')
rh=$(/var/usbrh/usbrh -1 2>&1)
limit=35
rh_judge=$(echo $rh | cut -c14-15)
if (( ${rh_judge} >= ${limit} )) ;then
alert=alert
else
unset alert
fi
echo ${date} ${rh} ${alert} >> /var/usbrh/usbrh_tes2.log
---スクリプト終わり---
このスクリプトで、ログを出力し、limit以上の数値になった場合、alertがログに書き込まれるようにできました。
そこでコレを少し改良してalert時にメールを飛ばせる様にしたいと思い下記のようにif文を差し替えました。

---if文始まり---
if (( ${rh_judge} >= ${limit} )) ;then
alert=alert
address="xxx@hogehoge.com"
subject="TemperatureAlert"

mail -s $subject $address << END
`$rh`
END
else
unset alert
fi
---if文終わり---

ところが、
echo ${date} ${rh} ${alert} >> /var/usbrh/usbrh_tes2.log
のあとの行(line23)で
line 23: syntax error: unexpected end of fileというのが出て
スクリプトが動かなくなってしまいました。

ログの書き込み部分は問題ないと思うのですが、原因がわかる方いらっしゃいますでしょうか。
ご指摘頂ければ幸いです。
宜しくお願いいたします。

温度管理をするため、CentOS4.4上で下記のようなスクリプトを動かしています。

---スクリプト始まり---
#!/bin/bash
date=$(date '+%Y/%m/%d(%a)/%R')
rh=$(/var/usbrh/usbrh -1 2>&1)
limit=35
rh_judge=$(echo $rh | cut -c14-15)
if (( ${rh_judge} >= ${limit} )) ;then
alert=alert
else
unset alert
fi
echo ${date} ${rh} ${alert} >> /var/usbrh/usbrh_tes2.log
---スクリプト終わり---
このスクリプトで、ログを出力し、limit以上の数値になった場合、alertがログに書き込まれるように...続きを読む

Aベストアンサー

気になるのは `$rh` かなぁ?
$rh に入っている文字列を, コマンドとして実行したいの? もしそうだとしても,
$rh | mail ...
の方が素直じゃないかなぁ.
あと, ヒアドキュメントを終わらせる END の前後に空白がないことも確認してください.

Qpingでポートの指定

pingでIPアドレスを指定して、通信できるかどうかというのは
よく使いますが、pingでポートを指定して応答するかどうかは調べられるのでしょうか?

よろしくお願いします

Aベストアンサー

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含むICMP)ではできません。

FTPの疎通確認であれば、クライアントからサーバに対するTCP/21通信(FTP-CMD)が可能であること(サーバからクライアントへのTCP/21からの応答を含む)+サーバからクライアントに対するTCP/20通信(FTP-DATA)が可能であること(クライアントからサーバへのTCP/21からの応答を含む)が必要でしょう。

監視ソフトによるものであれば、
・クライアントからサーバへのログイン(TCP/21)
・クライアントからサーバへのlsの結果(TCP/20)
で確認すればよいでしょう。

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含む...続きを読む


人気Q&Aランキング

おすすめ情報