b2 command finds ICU when called directly but not from indirect bash script variable
up vote
2
down vote
favorite
I have this strange issue with my bash script. I compile boost as part of it. The call from the script looks like this:
./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS" >> "$BOOST_LOG" 2>&1
That command works perfectly well. The log file shows that it finds ICU without a problem. However, if I change it to run from a variable, it no longer finds ICU (but it still compiles everything else):
bcmd="./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS""
$bcmd >> "$BOOST_LOG" 2>&1
What's the difference? I would like to be able to use the second approach so that I can pass the command into another function before running it.
bash boost compilation
This question has an open bounty worth +50
reputation from Brannon ending ending at 2018-11-25 21:28:54Z">in 4 days.
This question has not received enough attention.
add a comment |
up vote
2
down vote
favorite
I have this strange issue with my bash script. I compile boost as part of it. The call from the script looks like this:
./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS" >> "$BOOST_LOG" 2>&1
That command works perfectly well. The log file shows that it finds ICU without a problem. However, if I change it to run from a variable, it no longer finds ICU (but it still compiles everything else):
bcmd="./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS""
$bcmd >> "$BOOST_LOG" 2>&1
What's the difference? I would like to be able to use the second approach so that I can pass the command into another function before running it.
bash boost compilation
This question has an open bounty worth +50
reputation from Brannon ending ending at 2018-11-25 21:28:54Z">in 4 days.
This question has not received enough attention.
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I have this strange issue with my bash script. I compile boost as part of it. The call from the script looks like this:
./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS" >> "$BOOST_LOG" 2>&1
That command works perfectly well. The log file shows that it finds ICU without a problem. However, if I change it to run from a variable, it no longer finds ICU (but it still compiles everything else):
bcmd="./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS""
$bcmd >> "$BOOST_LOG" 2>&1
What's the difference? I would like to be able to use the second approach so that I can pass the command into another function before running it.
bash boost compilation
I have this strange issue with my bash script. I compile boost as part of it. The call from the script looks like this:
./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS" >> "$BOOST_LOG" 2>&1
That command works perfectly well. The log file shows that it finds ICU without a problem. However, if I change it to run from a variable, it no longer finds ICU (but it still compiles everything else):
bcmd="./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS""
$bcmd >> "$BOOST_LOG" 2>&1
What's the difference? I would like to be able to use the second approach so that I can pass the command into another function before running it.
bash boost compilation
bash boost compilation
asked Nov 8 at 19:04
Brannon
2,99212161
2,99212161
This question has an open bounty worth +50
reputation from Brannon ending ending at 2018-11-25 21:28:54Z">in 4 days.
This question has not received enough attention.
This question has an open bounty worth +50
reputation from Brannon ending ending at 2018-11-25 21:28:54Z">in 4 days.
This question has not received enough attention.
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
Try to use eval
when you want to execute a string as a command. This way, you won't have issues regarding strings that have spaces etc. The expanded cmd
string is not re-evaluated by bash
hence, things like "hi there"
are expanded as two separate tokens.
eval $bcmd >> "$BOOST_LOG" 2>&1
To demonstrate this behavior, consider this code:
cmd='echo "hi there"'
$cmd
eval $cmd
Which outputs to:
"hi there"
hi there
The token "hi there"
is not re-evaluated as a quoted string.
add a comment |
up vote
0
down vote
Don't use a variable to store complex commands involving quotes that are nested. The problem is when you call the variable with just $cmd
, the quotes are stripped incorrectly. Putting commands (or parts of commands) into variables and then getting them back out intact is complicated.
Quote removal is part of the one of the word expansions done by the shell. From the excerpt seen in POSIX specification of shell
2.6.7 Quote Removal
The quote characters ( backslash, single-quote, and double-quote) that were present in the original word shall be removed unless they have themselves been quoted.
Your example can be simply reproduced by a simple example. Assuming you have a few command flags (not actual ones)
cmdFlags='--archive --exclude="foo bar.txt"'
If you carefully look through the above, it contains 2 args, one --archive
and another for --exclude="foo bar.txt"
, notice the double-quotes which needs to be preserved when you are passing it.
Notice how the quotes are incorrectly split when I don't quote cmdFlags
, in the printf()
call below
printf "'%s' " $cmdFlags; printf 'n'
'--archive' '--exclude="foo' 'bar.txt"'
and compare the result with one with proper quoting done below.
printf "'%s' " "$cmdFlags"; printf 'n'
'--archive --exclude="foo bar.txt"'
So along with the suggestion of properly quoting the variable, the general suggestion would be to use an array to store the flags and pass the quoted array expansion
cmdArray=()
cmdArray=(./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS")
and pass the array as
"$cmdArrray[@]" >> "$BOOST_LOG" 2>&1
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Try to use eval
when you want to execute a string as a command. This way, you won't have issues regarding strings that have spaces etc. The expanded cmd
string is not re-evaluated by bash
hence, things like "hi there"
are expanded as two separate tokens.
eval $bcmd >> "$BOOST_LOG" 2>&1
To demonstrate this behavior, consider this code:
cmd='echo "hi there"'
$cmd
eval $cmd
Which outputs to:
"hi there"
hi there
The token "hi there"
is not re-evaluated as a quoted string.
add a comment |
up vote
0
down vote
Try to use eval
when you want to execute a string as a command. This way, you won't have issues regarding strings that have spaces etc. The expanded cmd
string is not re-evaluated by bash
hence, things like "hi there"
are expanded as two separate tokens.
eval $bcmd >> "$BOOST_LOG" 2>&1
To demonstrate this behavior, consider this code:
cmd='echo "hi there"'
$cmd
eval $cmd
Which outputs to:
"hi there"
hi there
The token "hi there"
is not re-evaluated as a quoted string.
add a comment |
up vote
0
down vote
up vote
0
down vote
Try to use eval
when you want to execute a string as a command. This way, you won't have issues regarding strings that have spaces etc. The expanded cmd
string is not re-evaluated by bash
hence, things like "hi there"
are expanded as two separate tokens.
eval $bcmd >> "$BOOST_LOG" 2>&1
To demonstrate this behavior, consider this code:
cmd='echo "hi there"'
$cmd
eval $cmd
Which outputs to:
"hi there"
hi there
The token "hi there"
is not re-evaluated as a quoted string.
Try to use eval
when you want to execute a string as a command. This way, you won't have issues regarding strings that have spaces etc. The expanded cmd
string is not re-evaluated by bash
hence, things like "hi there"
are expanded as two separate tokens.
eval $bcmd >> "$BOOST_LOG" 2>&1
To demonstrate this behavior, consider this code:
cmd='echo "hi there"'
$cmd
eval $cmd
Which outputs to:
"hi there"
hi there
The token "hi there"
is not re-evaluated as a quoted string.
edited 2 days ago
answered 2 days ago
ssemilla
2,197419
2,197419
add a comment |
add a comment |
up vote
0
down vote
Don't use a variable to store complex commands involving quotes that are nested. The problem is when you call the variable with just $cmd
, the quotes are stripped incorrectly. Putting commands (or parts of commands) into variables and then getting them back out intact is complicated.
Quote removal is part of the one of the word expansions done by the shell. From the excerpt seen in POSIX specification of shell
2.6.7 Quote Removal
The quote characters ( backslash, single-quote, and double-quote) that were present in the original word shall be removed unless they have themselves been quoted.
Your example can be simply reproduced by a simple example. Assuming you have a few command flags (not actual ones)
cmdFlags='--archive --exclude="foo bar.txt"'
If you carefully look through the above, it contains 2 args, one --archive
and another for --exclude="foo bar.txt"
, notice the double-quotes which needs to be preserved when you are passing it.
Notice how the quotes are incorrectly split when I don't quote cmdFlags
, in the printf()
call below
printf "'%s' " $cmdFlags; printf 'n'
'--archive' '--exclude="foo' 'bar.txt"'
and compare the result with one with proper quoting done below.
printf "'%s' " "$cmdFlags"; printf 'n'
'--archive --exclude="foo bar.txt"'
So along with the suggestion of properly quoting the variable, the general suggestion would be to use an array to store the flags and pass the quoted array expansion
cmdArray=()
cmdArray=(./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS")
and pass the array as
"$cmdArrray[@]" >> "$BOOST_LOG" 2>&1
add a comment |
up vote
0
down vote
Don't use a variable to store complex commands involving quotes that are nested. The problem is when you call the variable with just $cmd
, the quotes are stripped incorrectly. Putting commands (or parts of commands) into variables and then getting them back out intact is complicated.
Quote removal is part of the one of the word expansions done by the shell. From the excerpt seen in POSIX specification of shell
2.6.7 Quote Removal
The quote characters ( backslash, single-quote, and double-quote) that were present in the original word shall be removed unless they have themselves been quoted.
Your example can be simply reproduced by a simple example. Assuming you have a few command flags (not actual ones)
cmdFlags='--archive --exclude="foo bar.txt"'
If you carefully look through the above, it contains 2 args, one --archive
and another for --exclude="foo bar.txt"
, notice the double-quotes which needs to be preserved when you are passing it.
Notice how the quotes are incorrectly split when I don't quote cmdFlags
, in the printf()
call below
printf "'%s' " $cmdFlags; printf 'n'
'--archive' '--exclude="foo' 'bar.txt"'
and compare the result with one with proper quoting done below.
printf "'%s' " "$cmdFlags"; printf 'n'
'--archive --exclude="foo bar.txt"'
So along with the suggestion of properly quoting the variable, the general suggestion would be to use an array to store the flags and pass the quoted array expansion
cmdArray=()
cmdArray=(./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS")
and pass the array as
"$cmdArrray[@]" >> "$BOOST_LOG" 2>&1
add a comment |
up vote
0
down vote
up vote
0
down vote
Don't use a variable to store complex commands involving quotes that are nested. The problem is when you call the variable with just $cmd
, the quotes are stripped incorrectly. Putting commands (or parts of commands) into variables and then getting them back out intact is complicated.
Quote removal is part of the one of the word expansions done by the shell. From the excerpt seen in POSIX specification of shell
2.6.7 Quote Removal
The quote characters ( backslash, single-quote, and double-quote) that were present in the original word shall be removed unless they have themselves been quoted.
Your example can be simply reproduced by a simple example. Assuming you have a few command flags (not actual ones)
cmdFlags='--archive --exclude="foo bar.txt"'
If you carefully look through the above, it contains 2 args, one --archive
and another for --exclude="foo bar.txt"
, notice the double-quotes which needs to be preserved when you are passing it.
Notice how the quotes are incorrectly split when I don't quote cmdFlags
, in the printf()
call below
printf "'%s' " $cmdFlags; printf 'n'
'--archive' '--exclude="foo' 'bar.txt"'
and compare the result with one with proper quoting done below.
printf "'%s' " "$cmdFlags"; printf 'n'
'--archive --exclude="foo bar.txt"'
So along with the suggestion of properly quoting the variable, the general suggestion would be to use an array to store the flags and pass the quoted array expansion
cmdArray=()
cmdArray=(./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS")
and pass the array as
"$cmdArrray[@]" >> "$BOOST_LOG" 2>&1
Don't use a variable to store complex commands involving quotes that are nested. The problem is when you call the variable with just $cmd
, the quotes are stripped incorrectly. Putting commands (or parts of commands) into variables and then getting them back out intact is complicated.
Quote removal is part of the one of the word expansions done by the shell. From the excerpt seen in POSIX specification of shell
2.6.7 Quote Removal
The quote characters ( backslash, single-quote, and double-quote) that were present in the original word shall be removed unless they have themselves been quoted.
Your example can be simply reproduced by a simple example. Assuming you have a few command flags (not actual ones)
cmdFlags='--archive --exclude="foo bar.txt"'
If you carefully look through the above, it contains 2 args, one --archive
and another for --exclude="foo bar.txt"
, notice the double-quotes which needs to be preserved when you are passing it.
Notice how the quotes are incorrectly split when I don't quote cmdFlags
, in the printf()
call below
printf "'%s' " $cmdFlags; printf 'n'
'--archive' '--exclude="foo' 'bar.txt"'
and compare the result with one with proper quoting done below.
printf "'%s' " "$cmdFlags"; printf 'n'
'--archive --exclude="foo bar.txt"'
So along with the suggestion of properly quoting the variable, the general suggestion would be to use an array to store the flags and pass the quoted array expansion
cmdArray=()
cmdArray=(./b2 --reconfigure $PARALLEL link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH="$ICU_PREFIX" -sICU_LINK="$BOOST_ICU_LIBS")
and pass the array as
"$cmdArrray[@]" >> "$BOOST_LOG" 2>&1
answered 20 hours ago
Inian
37.3k63668
37.3k63668
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53214510%2fb2-command-finds-icu-when-called-directly-but-not-from-indirect-bash-script-vari%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown