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

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

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

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Q&A

解決済

2回答

1783閲覧

Shell Scriptでバックグラウンドから変数を加算したい。

kanashiikana

総合スコア11

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

0グッド

1クリップ

投稿2021/11/19 06:51

前提・実現したいこと

Shell Scriptを書いていて「&」を使ってバックグラウンドで並列処理をするときにバックグラウンド側から変数を加算したい。

発生している問題・エラーメッセージ

下のコードだと最後の出力が2にしかならない。

該当のソースコード

bash

1#!/bin/bash 2hoge(){ 3 echo -ne "${COUNT}\c" 4 echo -ne "\r\c" 5 ((COUNT++)) 6} 7COUNT=0 8for NUM in {1..999};do 9 hoge & 10done 11hoge 12sleep 1 13echo "${COUNT}" #最終的に1000になってほしい

試したこと

上のコードなら最後に「COUNT」に1000を足せばそれでもいいんですが、実際に使うときは関数内で足したり足さなかったりifで分岐して別の変数を加算したりしたいので、なんとかバックグラウンド側から変数に干渉したいです。

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

Windows11 WSL2 Ubuntu 20.04LTS

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

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

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

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

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

guest

回答2

0

ベストアンサー

異なるプロセス間で共有できるのはコマンドレベルだとファイルくらいしか無いので、
COUNTの値をファイルに書くのでしょうか。

Bash

1#!/bin/bash 2COUNTFILE=/tmp/COUNT 3trap "rm -f $COUNTFILE" 0 4 5hoge(){ 6 echo -ne "`cat $COUNTFILE`" 7 echo -ne "\r" 8 flock $COUNTFILE bash -c 'COUNT=`cat '$COUNTFILE'`;echo $((COUNT+1)) > '$COUNTFILE 9} 10echo 0 >$COUNTFILE 11for NUM in {1..999};do 12 hoge & 13done 14hoge 15sleep 1 16cat $COUNTFILE

投稿2021/11/19 17:07

編集2021/11/19 23:28
otn

総合スコア84557

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

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

kanashiikana

2021/11/20 08:05

実行してみたところ64GBあるメモリが一瞬で消費されて止まってしまいました。 それと途中で値が想定していない大きさになっていたのも確認できたのでやはりこれを実現するのは難しいということなんでしょうかね…… 回答ありがとうございました!別の方法を探してみます。
otn

2021/11/20 13:19

1つの処理がメモリーを大量に消費する処理であれば、そもそも1000平行というのが無理があるのでは? 平行数を現実的な数にしてみましょう。 > それと途中で値が想定していない大きさになっていたのも確認できたので COUNTの中身がということであれば、それはなにか記述ミスでしょうね。 1000平行であれば、1000は越えないです。 > これを実現するのは難しいということなんでしょうかね…… 難しい話では無いです。
kanashiikana

2021/11/23 06:04

>そもそも1000平行というのが無理があるのでは? なるほど!そりゃそうですよね。10平行を100回やるようにしてやれば問題なく動きました。 >1000平行であれば、1000は越えないです。 echo が重なって出力されてしまっていてうまく表示されていなかっただけでした。echoの使用回数を減らしたらうまくいきました。 無理なものかと思っていたので実装出来てとてもうれしいです。ありがとうございました! ```sh #!/bin/bash COUNTFILE=/tmp/COUNT trap "rm -f ${COUNTFILE}" 0 hoge(){ flock ${COUNTFILE} bash -c 'COUNT=`cat '${COUNTFILE}'`;echo $((COUNT+1)) > '${COUNTFILE} } echo 0 > ${COUNTFILE} for LOOP in {1..100};do for NUM in {1..9};do hoge & done hoge echo -ne "$(cat ${COUNTFILE})\c" echo -ne "\r\c" done sleep 1 cat ${COUNTFILE} ```
guest

0

なんとかバックグラウンド側から変数に干渉したいです。

無理です。バックグラウンド実行指定では、元のシェルのプロセスから別のプロセスが生成されます。異なるプロセス間で変数に干渉することはできません。
※生成時に元のプロセスから値をコピーして引き継ぐだけです。

なので「干渉」ではなく、例えば各ジョブにファイルに結果を追記させていって、最後にファイルの内容を集計するような方法だとか、そういった策を考える必要があります。

投稿2021/11/19 12:27

angel_p_57

総合スコア1672

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

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

kanashiikana

2021/11/20 08:06

なるほど……迂回策を考える必要があるのですね! 回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問