シェルスクリプトを利用するときに変数を配列として扱えるという記述を見たので、
以下のようなシェルスクリプトを作成したのですが、エラーが出てきてしまいます。
端末で直接入力すると、正しく動作します。そのためなぜエラーとなるのかわかりません。

環境はubuntu 10.10、
GNU bash, バージョン 4.1.5(1)-release (i686-pc-linux-gnu)
です。


----------------------
#!/bin/sh

list=(`ls`)
echo ${list[0]}
----------------------

3:Syntax error: "(" unexpected

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

とは GNU」に関するQ&A: GNUとは?

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

Linux 端末」に関するQ&A: RedHatLinuxの端末でftp

A 回答 (2件)

ディストリビューション等によっては、 shがbashへのリンクになっている場合もあります。

その場合、質問のスクリプトで動作します。

が、どうやら、あなたの環境ではshは拡張されていない元々の B-sh相当のもののようです。
配列はB-shそのものには無く、ksh,bash等の拡張版でのみ使えます。

#!/bin/bash

にしたら動くのではないでしょうか。(bashのパスが違っていたらそれに合せて)


> シェルスクリプトを利用するときに変数を配列として扱える

シェルスクリプトにも大きく B-shとC-shがあり、それぞれに本来の仕様(sh,csh)と、拡張版(ksh,bash,zsh,tcsh等)があります。
それぞれで詳細が違いますので、単純に考えないようにしましょう。
    • good
    • 0
この回答へのお礼

bashにしたら動きました。ありがとうございます。

お礼日時:2011/04/26 18:21

そのエラーは、シンタックスエラーですよね。



書式が違う場合と、括弧など足りなかったりする場合にでるエラーです。

まず、シェルの種類の勉強してください。

GNU bash,

となっていますが、スクリプトを見ると、SH ですね。これは互換で装備されているB-Shellを指しています。自分ではBASHを実行しているつもりが、実はUNIX時代のB-Shellを使用しています。もちろんエリアスなのでリンクしていなければですが。

次に、B-Shellの書式では ( ) は出てきません。

これは、C-Shell, K-Shell

しかありません。たぶん K-Shellの文献をよんだのでは。よくK-Shellを推奨している文献だと、B-Shellと混合して記載してあるのがみかけます。わざとなのか、本人がよくわかっていないのか? いずれにせよ。

B-Shellでの配列はありません。また () もありません。両方使えるのは

KSH

です。

http://homepage3.nifty.com/owl_h0h0/unix/job/UNI …
http://oshiete.goo.ne.jp/qa/1590859.html

http://homepage2.nifty.com/t-1000/linux/shell_ar …

ちなみに

#!/bin/besh

です
    • good
    • 0
この回答へのお礼

シェルスクリプトを使う方法として
#!/bin/sh
とまず書くというふうに、教えているサイトがあってこの様な問題が発生してしまいました。

おかげで#!/bin/beshがどのシェルでシェルスクリプトをまわすのか、という宣言であることがわかりました。

ありがとうございます。

お礼日時:2011/04/26 18:27

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

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

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

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

QC言語で、他の関数で配列を書き換えられないようにしたい

下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。

main関数の側では配列aの中身を表示します。
しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。
 私はfunc関数以外では、この配列の中身をいじられたくないのです。
 なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。
 
 とは言ったものの、多分できないだろうなあ、という気がします。
 できないならばできないでも仕方ないのですが、確信が持てないのです。

条件があります。
funcでは表示は行なわない。
配列aの中身を表示できるように、funcから呼び出し元へ、aのアドレスまたはaの先頭要素のアドレスがわかるような情報を返す。


#include <stdio.h>

char *func(int i)
{
static char a[]="AAAA";
a[i]='z';
return a;
}

int main(void)
{
int i;
for(i=0; i<4; i++)
{
char *p=func(i);
/* p[i]='X'; ★配列の中身を書き換えてしまう。 */
puts(p);
}
return 0;
}

下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。

main関数の側では配列aの中身を表示します。
しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。
 私はfunc関数以外では、この配列の中身をいじられたくないのです。
 なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。
 
 とは言ったものの、多分できないだろうなあ、とい...続きを読む

Aベストアンサー

staticな変数を使う限りは無理な話です。

func内でnon-staticな領域にコピーしたものをreturnする。
仕様を明記し,funcを呼び出した先で別のバッファへコピーして使うよう徹底する。

などの対策をするしかないでしょう。
こういう仕様では,逆にfunc関数以外で使っていた文字列の内容が funcの呼び出しによって意図せず書き換えられてしまう,といった逆のパターンも往々にしてあります。要注意。

Qあるシェルスクリプト内にある関数を、別のシェルスクリプトから呼ぶ事はできる?

件名の内容を具体的に申し上げると下の通りです。

あるシェルスクリプトから、その同一シェルスクリプト内にある関数を呼ぶ方法は既知です。が、他のシェルスクリプトにある関数を呼ぶ方法を知りません。方法が在る場合、簡単な文法をお教え頂けると幸いです。

以上どうぞ宜しくお願い致します。

Aベストアンサー

sh/bash系なら「. ファイル名」、
csh/tcsh系なら「source ファイル名」で
目的の関数を記述したスクリプトファイルをインポートすれば、
あとは同一ファイル上の関数と同じように扱えるはずです。

Qエクセルの配列関数の制限について

エクセルの配列関数の制限について


V列にX列・Y列・Z列・AA列・AB列・AC列・AE列・AG列・P列を参照した配列関数を
下のように入力しています。

{=SUM((Y$1:Y$500=F7)*(Z$1:Z$500=H7)*(AA$1:AA$500)*(P7="○"),(AB$1:AB$500=F7)
*(AC$1:AC$500=H7)*(AE$1:AE$500=H7)*(AG$1:AG$500)*(P7="×"))}

このY列・Z列・AA列・AB列・AC列・AE列・AG列は、ぞれぞれ200行くらいしか
文字が入力されていない場合には、配列関数の結果がうまく表示されました。


これらのセルの200行以降から300行・400行と項目を増やしていったところ、
配列関数の結果がうまく表示されないセルが出てきました。


これは、配列関数の参照するセルに制限があるということでしょうか?

Aベストアンサー

>SUMPRODUCT関数でも同様に0が表示されました。

F9キーで再計算しても「0」と表示されるなら、集計対象のセルがないということです。

>配列数式の結果で0が表示された件について、Y列・Z列の文字に半角と全角の括弧
「()」と「()」が混在していたことが原因と判明しました!

この意味が不明ですが(仮に混在しているとしても「0」と表示されることはない)、今回の「0」が表示される原因は解明できたということでしょうか?

>再計算されるまでに10分~15分かかり、メールやインターネットや他のエクセルなどが
使用できずに固まってしまいます。そのため、手動で再計算されるようにして何とか
使用しています。

再計算に1分以上かかることはほとんど考えられないのですが、いずれにしろ今回のようなデータ範囲の広い配列数式を多数入力するのは全く実用に堪えないと思いますので、数式部分を適宜「値」化して(古いデータを修正する場合は必要に応じて計算式を少しずつオートフィルする)、必要最小限の数式だけを残して作業することをお勧めします(VBAを使用しても計算に時間がかかる可能性が高いと思います)。

>SUMPRODUCT関数でも同様に0が表示されました。

F9キーで再計算しても「0」と表示されるなら、集計対象のセルがないということです。

>配列数式の結果で0が表示された件について、Y列・Z列の文字に半角と全角の括弧
「()」と「()」が混在していたことが原因と判明しました!

この意味が不明ですが(仮に混在しているとしても「0」と表示されることはない)、今回の「0」が表示される原因は解明できたということでしょうか?

>再計算されるまでに10分~15分かかり、メールやインターネットや他のエク...続きを読む

Qシェルスクリプトの変数について

表題の件について質問させていただきます。

シェルスクリプト内であるプログラムを走らせて
No is 2
という標準出力が得られたとします。
そのなかの2という文字を変数につめたいのですがなかなかうまくいきません。

良い方法をご存知の方ご教授よろしくお願いします。

Aベストアンサー

おっと,
s/[^0-9]//g
です.
g を忘れてました.
というか, これなら
no=`echo $str | tr -cd 0-9`
でよかったような気がする.

Q関数へのポインタ渡しでの配列の初期化について

はじめまして、C言語の基本的な質問をさせてください。

C言語で、外部関数へポインタで引数を渡す場合に、
関数に渡されるのはアドレスですよね?

で、渡された関数側でそのポインタの配列の初期化を
するときにはアドレスだけの情報だと、要素数がいくつ
あるか分からず、領域の破壊をしてしまいそうな気が
するのですが?いかがでしょうか?

また、関数かなんかで、配列の要素数が分かる関数が
あったような気がするのですが、それもアドレスだけ
でわかるのでしょうか?

Aベストアンサー

疑問に思っていらっしゃる通りです。

渡された関数側では、要素数がいくつあるかわかりません。
初期化をするならば、ポインタと一緒に、要素数の情報も渡してやる必要があります。

配列の要素数がわかる関数はありません。
マクロ(プリプロセッサ)で、配列要素数を計算するのは可能ですが、
これは使用場所が限定されています。
配列を宣言したすぐ近くでないと役に立ちません。
渡された関数側では使えません。

C言語では、配列はその要素数とともに扱う必要があり、
そこをうっかりするとバグが発生する危険があります。

Qコマンドの結果を変数へ代入@シェルスクリプト

Linux初心者です。

標記のとおり、シェルスクリプトで、コマンドの結果を変数へ代入することはできるでしょうか?

目的は、あるプログラムの開始時間から終了時間までの経過時間を計算して表示することです。時間を変数に代入しておいて計算したいのですが、方法がわかりません。(入出力のリダイレクト(|や>)、コマンドを引数に渡す方法(``)はわかったのですが...)

よろしくお願いいたします。

Aベストアンサー

time じゃ不十分なんだろうかと思いつつ
current_date=`date`
ってやるとシェル変数 current_date に「date が表示するはずの文字列」が代入できるけど, これとは違うのかなぁ?

Q関数を使った配列計算

関数を用いて配列を使った行列の演算(入力された行列の行列式、転置行列、逆行列)をするプログラムを見やすくしたいのですが、配列を関数に渡すやり方がわかりません。


出来れば実際のプログラムで教えてもらいたいです。よろしくお願いします。

Aベストアンサー

C言語の場合ですが、

void test(int a[10])
{
a[0] = 10;
}

int main(void)
{
int a[10];

test(a);
}

↑このような記述で配列を関数に渡すことが出来ます。
関数test内で書き換えた配列はmainでも反映されてます。

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

はじめまして、シェルスクリプトを勉強中の者です。

コマンドを変数にいれて、まとめました。
しかしコマンドの変数を呼びこもうとするとエラーになります。

============================================
#!/bin/sh
GREP="grep"
cat "${GREP} '^[0-9]' /home/hoge/test.nicdf"
============================================


================ シェル実行結果 =============
$ ./test.sh
cat: grep '^[0-9]' /home/hoge/test.nicdf: そのようなファイルやディレクトリはありません



どう書けば、エラーにならずに正常に動作するでしょうか?
ご教授の程よろしくお願いします。

Aベストアンサー

デバグ中なら、
#!/bin/sh

#!/bin/sh -x
にして実行してみるとよい。どんなコマンドが実行されるかがわかる。

たぶん、こんな感じに表示されるはず
+ cat 'grep '\''^[0-9]'\'' /home/hoge/test.nicdf'

最初の+はただの目印なのです。

あなたは、grep を使うときにこのような入力をしますか?ってことです

Q配列を書き換える関数を作成してみたいのですが、

配列を書き換える関数を作成してみたいのですが、

int a[10]={3,5,7,6,7,8,10,2,3,11};

上記のような配列があるとして、
0~9のうち特定の添字を指定して、a[]の中身を書き換える関数を作る場合は、
どのような方法があるのでしょうか?

Aベストアンサー

#4 訂正
>ネストを似やすくするため全角スペースを入力しています
ネストを見やすくするため全角スペースを入力しています

どうせなので
多分間違いだとは思いますが#3さんのは
>change(a, a, 2);
change(a, 1, 2); の打ち間違いだと思われます

更に思いつき#1さんのをちょっと書き方変えてみました
>void change(int a[],int i,int n){
>a[i]=n;
>}

コール側
change(a, 1, 2);    //a[1] に2を代入する
関数側
void change(int *addr, int pt, int newdata){
  *(addr+pt) = newdata;
}

もありかな(同じくコンパイルなどはしてません)

Qbashシェルスクリプトで変数を使う

bashシェルスクリプト内で変数を使いたいです。
Linux内の設定ファイルを参考に、
・変数名=その内容、で設定
・${変数名} 、で呼び出す
だと判断し、以下のように使っています。

#!/bin/bash
WORK=/home/aaa/
cd ${WORK}

その後検索したところ、
「呼び出すには、$変数名 のように記述する」との説明を見かけ、
実際$の後に変数名を付けるだけでも認識したのですが、
{ }は付けても付けなくてもよいのでしょうか。
{ }が必要な場合もあるのでしょうか。

Aベストアンサー

たとえば、
WORKSという変数を追加したとします。
WORKS=/home/bbb/
また、/home/aaa/S
というディレクトリがあったとして

cd ${WORK}S

cd $WORKS
では結果が違ってきます。

どこまでが変数か明示する必要があるときに{}を使います。

あまり詳しくないのでこのくらいしかわかりませんが・・・


人気Q&Aランキング

おすすめ情報