web-dev-qa-db-ja.com

時計を強制的にbashで実行する方法

問題は、watchを実行するとshが実行され、次のエラーが発生することです。

sh: 1: func1: not found

ここにコードがあります:

#!/bin/bash

func1(){
  echo $1
}

export -f func1

watch func1
19
Rachid Oussanaa

わかりましたので、あなたのアプローチにはいくつかの問題があります。

シェル間で移植できない関数をエクスポートしています。 watchは、システムでbashではない/bin/shを使用してコマンドを実行します。そして、それがどんなシェルであっても、それは関数のエクスポートを尊重しないため、エラーが発生します。

次に、コマンドをwatch bash -c 'func1'のようなものに変更できますが、これもうまく機能しない可能性があります。
ここでの理由は、スクリプトによって設定された変数が関数で使用できないためです。必要なものをエクスポートできるかもしれませんが、それは面倒になります。

最も安全な解決策は、func1を単独でスクリプトに入れ、そのスクリプトを呼び出すことです。

つまり、次のことを試してください。

watch bash -c func1
10
Patrick

watchのデフォルトのシェルは/bin/shです。シェルは、他のタイプのシェルからエクスポートされた変数または関数を継承しません。

システムが/bin/sh/bin/bash(または現在のシェル)にシンボリックリンクしない場合は、-xまたは--execを使用してwatchにシェルを実行するように指示できます。

watch -x bash -c "my_func"

または

watch --exec bash -c "my_func"

これは、watch bash -c "test_watch"を使用して子プロセス(この場合はbash)を生成するために--execを使用せず、bashをずっと維持するため、/bin/shとは異なります。他の回答で指摘されているように、現在の環境に高度に結合されている関数をエクスポートする場合(つまり、他の変数または関数が必要な場合)、これは面倒になる可能性があります。


例:

test_watch() { echo 'Working!'; }
export -f test_watch
watch --exec bash -c "test_watch"

おなじみの

Every 2.0s: bash -c test_watch                                   Thu Mar 31 11:15:56 2016

Working!
16
Andy

スクリプト内からwatchを実行する理由なぜこのシェルスクリプトがないのですか。

$ cat func1 
#!/bin/bash

func1(){
  echo $1
}

func1 $1

...そしてそれをそのように実行します...

$ watch func1 foo
4
Red Cricket