2017-07-26 14 views
0

C++コードから次のbashスクリプトを実行します。私は、私もbash -cをしようとしただけでなく、生産エラーよう複数行bashスクリプトをC++コードから文字列として実行する

sh: 6: [[: not found 
sh: 8: [[: not found 
sh: 9: [[: not found 

、として、コマンドを実行し、その出力をキャプチャするsystem()またはpopenを使用しようとしますが、彼らが、内蔵されたSHはそれを実行しようとするので、私はエラーを取得しますなぜなら、複数行の文字列は扱えないと思うからです。

いくつかの理由から、以下のスクリプトを.shファイルに入れて実行することはできません。したがって、このスクリプトはC++コードの文字列として格納して実行する必要があります。どのようにこれを行うことができますか?

#!/bin/bash 
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do 
    (
     syspath="${sysdevpath%/dev}" 
     devname="$(udevadm info -q name -p $syspath)" 
     [[ "$devname" == "bus/"* ]] && continue 
     eval "$(udevadm info -q property --export -p $syspath)" 
     [[ -z "$ID_SERIAL" ]] && continue 
     [[ "${ID_SERIAL}" == *"PX4"* ]] && echo "/dev/$devname" 
    ) 
done 

サンプルコード:

メモ:C++ escapped文字列にテキストを変換するためにthis toolを使用することができます。

int main() { 
    std::cout << system("#!/bin/bash\nfor sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do\n (\n  syspath=\"${sysdevpath%/dev}\"\n  devname=\"$(udevadm info -q name -p $syspath)\"\n  [[ \"$devname\" == \"bus/\"* ]] && continue\n  eval \"$(udevadm info -q property --export -p $syspath)\"\n  [[ -z \"$ID_SERIAL\" ]] && continue\n  [[ \"${ID_SERIAL}\" == *\"PX4\"* ]] && echo \"/dev/$devname\"\n )\ndone"); 

    return 0; 
} 
+0

スクリプトを実際の*ファイル*に入れて実行してみませんか? –

+0

なぜ '(..)'を使ってサブ・シェルで文を実行しますか? – Inian

+0

このスクリプトはライブラリで実行されるため、余分な.shファイルをライブラリに同梱する必要はありません。また、ライブラリをUnrealエンジンビルドシステムで使用すると、作業が複雑になります。 – ShitalShah

答えて

1

複数行のスクリプトを1行にすることができます。

FOO=`uname` 
if [ "$FOO" == "Linux" ]; then 
    echo "You are using 'Linux'" 
fi 

上記セミコロン使用することにより、単一ラインに変換することができますコード:systemコマンドを使用することができますをエスケープ適切で今

FOO=`uname`; if [ "$FOO" == "Linux" ]; then echo "You are using 'Linux'"; fi 

が実行するのは、次ののスクリプトを持っていると仮定しましょうそれはあなたのプログラムから次のようになります:

#include <cstdlib> 
#include <string> 

int main() { 
    std::string foo { 
     "bash -c '" 
     "FOO=`uname`; " 
     "if [ \"$FOO\" == \"Linux\" ]; then " 
     "echo \"You are using 'Linux'.\"; " 
     "fi'" 
    }; 
    system(foo.c_str()); 
} 

メモtハット隣接の文字列リテラルはコンパイラによって連結されているので、読みやすくするために複数行のスクリプトのように見えるようにすることができます。

+1

私は同様のアプローチを試みましたが、これまでにはうまくいきませんでした。あなたの答えの鍵では、エスケープされた文字列をエスケープするというさらなる問題を避けるために、完全なコマンドにはシングルクォートを使用することです:)。また、細かい細かいディテールは追加しないでください。その後。 – ShitalShah

関連する問題