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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Node-RED

Node-REDは、ビジュアルプログラミング向けのフローベース開発ツールです。ブラウザベースのUIになっており、さまざまなノード(Node)を結びつけることでフローを作成でき、処理を実現します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

解決済

3回答

1290閲覧

linuxの環境変数を変更して、node-red上で使いたいです

ysk_snn

総合スコア21

Node-RED

Node-REDは、ビジュアルプログラミング向けのフローベース開発ツールです。ブラウザベースのUIになっており、さまざまなノード(Node)を結びつけることでフローを作成でき、処理を実現します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

1グッド

0クリップ

投稿2023/02/03 04:17

編集2023/03/08 07:53

実現したいこと

ラズパイのnode-redにおいて、自分で設定した環境変数(自分のIPアドレス)を使用したいです。

試したこと

ラズパイのコマンドラインで、

$ MYIP=`hostname -I` $ export MYIP

と記入して、

$ env

で確認すると、環境変数にMYIPが追加されたことを確認しました。
しかし、ラズパイのnode-redにおいて、changeノードで$MYIPを出力すると、""と出力されてしまいます。

また、/etc/rc.local において、

$ MYIP=`hostname -I` $ export MYIP

を追記して再起動してみましたが、

$ env

で環境変数を確認すると、MYIPが登録されていませんでした。

大きな勘違いをしているかもしれません、ご指導お願いいたします。

20230206追記

/lib/systemd/system/nodered.service内で、[Service]下に、
Environment=MYIP=XXX.XXX.XXX.XXX と記入したところ、node-red内で$MYIPを出力するとXXX.XXX.XXX.XXXが出力できるようになりました。
しかし、ラズパイが複数台あるので、
Environment=MYIP=$(hostname -I)のように指定したいのですが、こちらだとnode-red内で$MYIPを出力すると$(hostnameが出力されてしまって困っています...

20230206追記2

node-redをサービスで起動しているので、それより早くenvironmentを更新できるように、
/etc/systemd/system/set-envvar.serviceというファイルを作って、以下の文章を記入しました。
MYIPがすでにある場合は更新、ない場合は追加、みたいなつもりです。

[Unit] Description=Update or Add MYIP in /etc/environment Before=nodered.service [Service] ExecStartPre=/bin/sh -c "if grep -q MYIP /etc/environment; then sed -i 's/MYIP=.*/MYIP=$(hostname -I)/g' /etc/environment; else echo MYIP=$(hostname -I) >> /etc/environment; fi" [Install] WantedBy=multi-user.target

ところが再起動後に/etc/environmentを確認してもMYIPが追加されていなかったので、systemctl list-units -all --type=serviceで確認したところ、
set-envvar.serviceLOADbad-settingになっていました。
原因がよくわからずに困っています。

20230207 追記3

/etc/environment での環境変数の設定は今回は避けるべきという指摘をいただいたので、
追記2で作ったset-envvar.serviceファイルは破棄して、/lib/systemd/system/nodered.serviceにおいて以下のような追記をしました。

ExecStartPre=/bin/sh -c "sudo /bin/systemctl set-environment MYIP=$(/bin/hostname -I)"

しかし、node-redのUI上において、デバグノードで$MYIPを出力しても""が返ってきます。
また、mqtt outノードでは$MYIPをトピックとしたところ、"不正なトピックが設定されています"と表示されました。

20230308追記4

"~/.node-red内のenvironmentという名称のファイル"を使用できなかったため、ラズパイに入っていたnode および node-redのバージョンを上げました。(これはこれで手間取ってしまいました)
node : v10.21.0 --> v16.19.1
node-red : v1.0.6 --> v3.0.2
しかしながら、~/.node-red/environment を作ってそこに環境変数を指定しても、node-red内では使用することができませんでした。やり方が間違っていたのかもしれませんが、今回は諦めてしまいました。

結局以下3点の変更を加えることで、node-red内で使える環境変数にIPアドレスを指定することができました。
皆さん、いろいろ教えてくださってありがとうございました。皆さんのアドバイスを組み合わせた感じになりましたが、今回は86ps様をベストアンサーにいたします。

①ノードレッドのサービス(/lib/systemd/system/nodered.service)に以下の環境変数を追加

[Service] Environment=MYIP=192.168.XXX.XXX

②ノードレッドサービス内の環境変数を変更する、以下のシェルスクリプト(/usr/local/bin/update_myip.sh)を追加して、chmod +x update_myip.shで実行可能に設定

#!/bin/bash new_ip=$(grep -A 3 'wlan0' /etc/dhcpcd.conf | grep ip_address | grep -o '192.168.[0-9]\+.[0-9]\+') if [ -z "$new_ip" ]; then echo "No IP address containing '192.168' is found." else if grep -q 'MYIP=' /lib/systemd/system/nodered.service; then sed -i "s/MYIP=.*/MYIP=$new_ip/" /lib/systemd/system/nodered.service echo "MYIP variable has been updated to $new_ip" else echo "some error occurred" fi fi

③update_myip.shを実行するサービスupdate-myip-in-nodered.serviceを追加(/etc/systemd/system/update-myip-in-nodered.service)

[Unit] Description=Update MYIP Before=nodered.service [Service] Type=oneshot ExecStart=sudo /bin/sh -c 'sudo /usr/local/bin/update_myip.sh' [Install] WantedBy=multi-user.target
86ps👍を押しています

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

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

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

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

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

dtn8kp6s

2023/02/03 16:50

node-redはどのように起動しているのでしょうか。 起動させるスクリプトやプログラムから環境変数を設定できるかもしれません。
ysk_snn

2023/02/06 02:30

コメントありがとうございます! node-redは起動時に自動で起動するようにしています。 /lib/systemd/system/nodered.service 内で、[Service]下に、 Environment=MYIP=XXX.XXX.XXX.XXX と記入したところ、node-red内で$MYIPを出力するとXXX.XXX.XXX.XXXが出力できるようになったのですが、 ラズパイが複数台あるので、 Environment=MYIP=$(hostname -I) のように指定したかったのですが、こちらだとnode-red内で$MYIPを出力すると$(hostname が出力されてしまって困っています...
guest

回答3

0

ベストアンサー

systemd.service の Environmentでは、シェルの構文は使えません。

滅多にipアドレスを変えないのであれば、以下のように、/etc/environment の中に環境変数MYIPを設定すればよいだけです。

shell

1echo MYIP=$(hostname -I) >> /etc/environment

滅多にipアドレスを変えないのであればこれで十分ですが、IPアドレスを変えるたびに以下のように/etc/environment を変更しなければなりません。

shell

1# MYIP変更 2sed -i "s/MYIP=.*/MYIP=$(hostname -I)/g" /etc/environment

別の方法としては、
/lib/systemd/system/nodered.service の中身の、ExecStartPreを以下のように設定すると良いと思います

ini

1[Service] 2ExecStartPre=/bin/sh -c "/bin/systemctl set-environment MYIP=$(/bin/hostname -I)"

このようにすると、systemdがNode-REDを起動させる前に、systemdに環境変数MYIPを「/bin/hostname -I」のコマンドの結果に設定するシェルが実行されます。
これであればNode-REDを起動させる前に、(/bin/hostname -I) の結果がsystemd で適用され、Node-REDとそれ以降に起動したサービスでこの環境変数が使えます。


追記2より

systemd unit ファイルの書き方が間違っています。
ExecStartPre=ではなく、ExecStart=にするべきです。

また、nodered.service が起動する前に /etc/environment を変更するサービスを作れたとしても、/etc/environment を変更する前に /etc/environment の環境変数が適用されてしまう可能性があります。

さらに言えば、nodered.service が起動する前に、/etc/environment が適用される保証はありません。起動時のいつどこでログイン(pam認証)されているかが不明瞭なためです。/etc/environment は pam_env.so によってログイン時に読み込まれますが、これについての情報が少ない上に私はPAMについて詳しくないため断言はできないですが、再起動やログインをせずに起動中に/etc/environment を適用する方法はおそらくないです。(そもそもPAM自体、ユーザ認証のためのものですから、ログイン後に使われる環境変数のために /etc/environment が存在するのでしょう。)
したがって、/etc/environment で設定するのは好ましくないです。

上記の「別の方法としては、…」のような、起動中にsystemdに環境変数を設定する方法の方が良いと思います。
また、systemdがNode-REDを起動させる前に、systemdに環境変数を設定するサービスを作っても良いと思いますが、noderedのために環境変数を一つ追加するだけであれば、nodered.service のExecStartPre=で、systemdに環境変数を設定するだけで十分だと思います。


コメントより
/lib/systemd/system/nodered.service の内容を調べてみましたが、ユーザー権限で実行するみたいですね。確認してなくてすみません。。

Node-REDの環境変数の設定方法について調べてみたら、以下のページが見つかりました。

環境変数を利用する : Node-RED日本ユーザ会
https://nodered.jp/docs/user-guide/environment-variables

「Node-REDユーザディレクトリ~/.node-red内のenvironmentという名称のファイル内に配置することで定義できます。」とありました。
しかし、このenvironmentファイルでもシェルが実行されないと思われるため

以下のようにnodered.serviceを起動する前に、~/.node-red/environment を更新するサービスを作成

/etc/systemd/system/myip-in-nodered.service

ini

1[Unit] 2Description=Update or Add MYIP in ~/.node-red/environment 3Before=nodered.service 4 5[Service] 6Type=oneshot 7# ~/.node-red/environment にMYIPを設定 8ExecStart=/bin/sh -c "if grep -q MYIP <homeディレクトリ>/.node-red/environment; then sed -i 's/MYIP=.*/MYIP=$(hostname -I)/g' <homeディレクトリ>/.node-red/environment; else echo MYIP=$(hostname -I) >> <homeディレクトリ>/.node-red/environment; fi" 9User=<ユーザー名> 10Group=<グループ名> 11 12[Install] 13WantedBy=multi-user.target

shell

1$ sudo systemctl enable myip-in-nodered

このような方法で、できないでしょうか。
上記実行する場合、/lib/systemd/system/nodered.service に EnvironmentFile=-<ホームディレクトリ>/.node-red/environment
が設定されているか確認してください。

投稿2023/02/06 05:43

編集2023/02/07 05:16
dtn8kp6s

総合スコア66

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

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

ysk_snn

2023/02/07 00:38

コメントありがとうございます! /etc/environment での設定を避けるべき理由も教えてくださってありがとうございます。 「別の方法としては、…」を試してみたのですが、Access deniedが出たので、 ExecStartPre=/bin/sh -c "sudo /bin/systemctl set-environment MYIP=$(/bin/hostname -I)" としてみたところ、実行は問題なくできたのですが、node-redにおいて MYIPをデバグノードで出力すると、""が返ってきて、 nodered.serviceのログを確認すると、MYIPをトピックとしているmqttノードにおいて"不正なトピックが設定されています"とエラー文が出ていました...
guest

0

環境変数はプロセス固有のデータなので、/etc/rc.localで設定した環境変数は、rc.localのシェルプロセス内およびそこから起動されたプロセスにだけ影響します。他のプロセスには無関係。
また、コマンドライン(とあるシェルプロセス)で設定した環境変数は、そのシェルプロセスとそのコマンドラインから起動されたプロセスにだけ影響します。

node-red をとあるユーザーでログインして起動しているなら、そのユーザーの~/.bash_profile等で設定します。
OS起動で自動的に起動しているなら、起動スクリプトの中で設定するか、起動スクリプトから読み込んでいるファイルの中で設定するか。

あるいは、他の方の回答にあるように/etc/environmentに書くと効くかと思いますが、このファイルはシェルが処理するわけじゃないのでコマンド実行や他の環境変数参照などシェルの機能は使えません。

MYIP=`hostname -I`

と書くと、そのままの文字列がセットされます。

MYIP=10.1.2.3

のように設定したい文字列をそのまま書く必要があります。

投稿2023/02/03 05:29

otn

総合スコア84830

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

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

ysk_snn

2023/02/03 06:28

コメントありがとうございます。 今回のラズパイはログインせずに使用したいので、~/.bash_profileではうまくいきませんでした... 環境変数を設定したいラズパイの台数が結構多かったので、変数で指定したかったのですが、 /etc/environment に目視で確認して設定するしかないのでしょうか...
otn

2023/02/03 06:52

> /etc/environment に目視で確認して設定するしかないのでしょうか... /etc/environment に自分で書き込むならそうですね。 回答に書いたように、もしnode-redの起動がシェルスクリプトを経由していればその中で設定するか、 あるいは、シェルスクリプト経由の起動になってなければ、node-redよりも前に起動するサービスを自分で作ってそのスクリプト内で/etc/environmentを更新するか。
otn

2023/02/03 07:05

あるいは、簡便には、/etc/rc.local で hostname -I を使って /etc/environment を更新するようにしておくと、次回OS起動では間に合わないと思いますが、次々回のOS起動では更新後の/etc/environmentでnode-redが起動すると思います。 つまり、 echo MYIP=`hostname -I` > /etc/environment を/etc/rc.localに書いて、OSを2回再起動。
ysk_snn

2023/02/06 08:02

再度のご返答ありがとうございます。 "node-redよりも前に起動するサービスを自分で作ってそのスクリプト内で/etc/environmentを更新する"をやってみたのですが、エラーが出てしまっています... 追記したので、ご確認いただけますと大変ありがたいです。
guest

0

Node-REDで環境変数にアクセスするためには、Node-REDが動作している環境でグローバルに環境変数を設定する必要があります。

環境変数は、Raspberry Pi の /etc/environment ファイルで設定します。そのファイルに以下の行を追加してください。

MYIP="hostname -I"

ファイルを保存した後、Node-REDを再起動すると、変更が有効になります。これで、Node-REDのフローで環境変数MYIPにアクセスできるようになりました。

変更したノードで、process.env.MYIPを使用して、MYIP環境変数の値にアクセスします。

/etc/rc.localファイルについてですが、rc.localは環境が完全に整う前に実行されるため、このファイルで設定した環境変数はNode-REDで利用できません。代わりに /etc/environment ファイルで環境変数を設定してみてください。

投稿2023/02/03 04:22

yori3963

総合スコア17

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

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

ysk_snn

2023/02/03 04:42

回答ありがとうございます! /etc/rc.local だとうまくいかない理由も教えていただいてありがとうございます。 /etc/environmentに追記してみたのですが、/etc/environmentにはシェルの機能がないみたいで、再起動後の環境変数を確認すると、MYIP=hostname -I となっておりました... 他に方法をご存じでしたら教えていただけるとありがたいです。
yori3963

2023/02/05 10:33

/etc/environmentにはシェルスクリプトを書けないので、以下のようなスクリプトを作成して、起動時に実行することができます。 例:/etc/profile.d/set_my_ip.sh bash Copy code #!/bin/bash MYIP=$(hostname -I) export MYIP このスクリプトを作成した後、起動時に/etc/profile.d/set_my_ip.shが自動的に実行されるようになります。 また、上記スクリプトを作成した後、以下のコマンドを実行すると、環境変数MYIPが正常に設定されているか確認することができます。 shell Copy code $ source /etc/profile.d/set_my_ip.sh $ env | grep MYIP
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問