io redirection not working when command stored in a variable

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite
1












The following command lets me check if a webpage has specific content. It does not output anything unless the content is found.



curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'


The problem is, when I add this to a shell script, the output isn't suppressed any more.



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"

$TEST1
if [[ $? != 0 ]]; then
#do something if exit status of last command not equal to zero
fi


I have the same problem if I try to store the output of the script in a variable (VAL1)



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"
VAL1+=$($TEST1)
echo "result should be blank or the found grep $VAL1"


Why does 2>&1 work as expected when running the command directly, but when added to a script the output is directed in the command line?



Update



Jeffs hint's in the comments got me going in the right direction. The accepted answer is correct. The work around I did for my script was to move the code I originally tried to assign to a variable to be in a function and use $( ... ). This way everything ran as expected:



#!/bin/bash
# note that -z checks if variable is empty
test1()
VAL1=$(curl -v --silent https://somedomain.com/somepage.html 2>&1

test1
echo $VAL1









share|improve this question























  • pls show current output and expected output
    – user1700494
    Sep 27 at 14:46










  • It’s an interesting distinction, to me, given that redirection comes after parameter expansion in the sequence of operations.
    – Jeff Schaller
    Sep 27 at 14:52










  • Notice what happens under set -x: curl ... '2>&1' ... with the single-quotes around the redirection.
    – Jeff Schaller
    Sep 27 at 14:54






  • 2




    Relating: unix.stackexchange.com/a/269259/117549
    – Jeff Schaller
    Sep 27 at 14:56














up vote
1
down vote

favorite
1












The following command lets me check if a webpage has specific content. It does not output anything unless the content is found.



curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'


The problem is, when I add this to a shell script, the output isn't suppressed any more.



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"

$TEST1
if [[ $? != 0 ]]; then
#do something if exit status of last command not equal to zero
fi


I have the same problem if I try to store the output of the script in a variable (VAL1)



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"
VAL1+=$($TEST1)
echo "result should be blank or the found grep $VAL1"


Why does 2>&1 work as expected when running the command directly, but when added to a script the output is directed in the command line?



Update



Jeffs hint's in the comments got me going in the right direction. The accepted answer is correct. The work around I did for my script was to move the code I originally tried to assign to a variable to be in a function and use $( ... ). This way everything ran as expected:



#!/bin/bash
# note that -z checks if variable is empty
test1()
VAL1=$(curl -v --silent https://somedomain.com/somepage.html 2>&1

test1
echo $VAL1









share|improve this question























  • pls show current output and expected output
    – user1700494
    Sep 27 at 14:46










  • It’s an interesting distinction, to me, given that redirection comes after parameter expansion in the sequence of operations.
    – Jeff Schaller
    Sep 27 at 14:52










  • Notice what happens under set -x: curl ... '2>&1' ... with the single-quotes around the redirection.
    – Jeff Schaller
    Sep 27 at 14:54






  • 2




    Relating: unix.stackexchange.com/a/269259/117549
    – Jeff Schaller
    Sep 27 at 14:56












up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





The following command lets me check if a webpage has specific content. It does not output anything unless the content is found.



curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'


The problem is, when I add this to a shell script, the output isn't suppressed any more.



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"

$TEST1
if [[ $? != 0 ]]; then
#do something if exit status of last command not equal to zero
fi


I have the same problem if I try to store the output of the script in a variable (VAL1)



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"
VAL1+=$($TEST1)
echo "result should be blank or the found grep $VAL1"


Why does 2>&1 work as expected when running the command directly, but when added to a script the output is directed in the command line?



Update



Jeffs hint's in the comments got me going in the right direction. The accepted answer is correct. The work around I did for my script was to move the code I originally tried to assign to a variable to be in a function and use $( ... ). This way everything ran as expected:



#!/bin/bash
# note that -z checks if variable is empty
test1()
VAL1=$(curl -v --silent https://somedomain.com/somepage.html 2>&1

test1
echo $VAL1









share|improve this question















The following command lets me check if a webpage has specific content. It does not output anything unless the content is found.



curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'


The problem is, when I add this to a shell script, the output isn't suppressed any more.



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"

$TEST1
if [[ $? != 0 ]]; then
#do something if exit status of last command not equal to zero
fi


I have the same problem if I try to store the output of the script in a variable (VAL1)



#!/bin/bash
TEST1="curl -v --silent https://somedomain.com/somepage.html 2>&1 | grep 'some content'"
VAL1+=$($TEST1)
echo "result should be blank or the found grep $VAL1"


Why does 2>&1 work as expected when running the command directly, but when added to a script the output is directed in the command line?



Update



Jeffs hint's in the comments got me going in the right direction. The accepted answer is correct. The work around I did for my script was to move the code I originally tried to assign to a variable to be in a function and use $( ... ). This way everything ran as expected:



#!/bin/bash
# note that -z checks if variable is empty
test1()
VAL1=$(curl -v --silent https://somedomain.com/somepage.html 2>&1

test1
echo $VAL1






bash shell-script io-redirection variable






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 27 at 16:33

























asked Sep 27 at 14:33







user310115


















  • pls show current output and expected output
    – user1700494
    Sep 27 at 14:46










  • It’s an interesting distinction, to me, given that redirection comes after parameter expansion in the sequence of operations.
    – Jeff Schaller
    Sep 27 at 14:52










  • Notice what happens under set -x: curl ... '2>&1' ... with the single-quotes around the redirection.
    – Jeff Schaller
    Sep 27 at 14:54






  • 2




    Relating: unix.stackexchange.com/a/269259/117549
    – Jeff Schaller
    Sep 27 at 14:56
















  • pls show current output and expected output
    – user1700494
    Sep 27 at 14:46










  • It’s an interesting distinction, to me, given that redirection comes after parameter expansion in the sequence of operations.
    – Jeff Schaller
    Sep 27 at 14:52










  • Notice what happens under set -x: curl ... '2>&1' ... with the single-quotes around the redirection.
    – Jeff Schaller
    Sep 27 at 14:54






  • 2




    Relating: unix.stackexchange.com/a/269259/117549
    – Jeff Schaller
    Sep 27 at 14:56















pls show current output and expected output
– user1700494
Sep 27 at 14:46




pls show current output and expected output
– user1700494
Sep 27 at 14:46












It’s an interesting distinction, to me, given that redirection comes after parameter expansion in the sequence of operations.
– Jeff Schaller
Sep 27 at 14:52




It’s an interesting distinction, to me, given that redirection comes after parameter expansion in the sequence of operations.
– Jeff Schaller
Sep 27 at 14:52












Notice what happens under set -x: curl ... '2>&1' ... with the single-quotes around the redirection.
– Jeff Schaller
Sep 27 at 14:54




Notice what happens under set -x: curl ... '2>&1' ... with the single-quotes around the redirection.
– Jeff Schaller
Sep 27 at 14:54




2




2




Relating: unix.stackexchange.com/a/269259/117549
– Jeff Schaller
Sep 27 at 14:56




Relating: unix.stackexchange.com/a/269259/117549
– Jeff Schaller
Sep 27 at 14:56










2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










Jeff Schaller's comment link is on the nose. The key message from the bash manual (https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion)




When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.



  1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

  2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.


  3. Redirections are performed as described above (see Redirections).

  4. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.



Step 1 identifies the redirections and saves them.

Step 2 is where variable expansion happens.



The shell sees no redirections in step 1.



Also relevant: I'm trying to put a command in a variable, but the complex cases always fail!






share|improve this answer





























    up vote
    1
    down vote













    The bad solution is to force a double evaluation :



    eval "$TEST1"


    The good solution is to split the command semantically (url, content) :



    curl -v --silent "$url" |& grep "$content"


    Note : |& is syntactic sugar for 2>&1 |






    share|improve this answer




















      Your Answer







      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "106"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f471842%2fio-redirection-not-working-when-command-stored-in-a-variable%23new-answer', 'question_page');

      );

      Post as a guest





























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote



      accepted










      Jeff Schaller's comment link is on the nose. The key message from the bash manual (https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion)




      When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.



      1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

      2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.


      3. Redirections are performed as described above (see Redirections).

      4. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.



      Step 1 identifies the redirections and saves them.

      Step 2 is where variable expansion happens.



      The shell sees no redirections in step 1.



      Also relevant: I'm trying to put a command in a variable, but the complex cases always fail!






      share|improve this answer


























        up vote
        2
        down vote



        accepted










        Jeff Schaller's comment link is on the nose. The key message from the bash manual (https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion)




        When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.



        1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

        2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.


        3. Redirections are performed as described above (see Redirections).

        4. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.



        Step 1 identifies the redirections and saves them.

        Step 2 is where variable expansion happens.



        The shell sees no redirections in step 1.



        Also relevant: I'm trying to put a command in a variable, but the complex cases always fail!






        share|improve this answer
























          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          Jeff Schaller's comment link is on the nose. The key message from the bash manual (https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion)




          When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.



          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.


          3. Redirections are performed as described above (see Redirections).

          4. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.



          Step 1 identifies the redirections and saves them.

          Step 2 is where variable expansion happens.



          The shell sees no redirections in step 1.



          Also relevant: I'm trying to put a command in a variable, but the complex cases always fail!






          share|improve this answer














          Jeff Schaller's comment link is on the nose. The key message from the bash manual (https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion)




          When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.



          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.


          3. Redirections are performed as described above (see Redirections).

          4. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.



          Step 1 identifies the redirections and saves them.

          Step 2 is where variable expansion happens.



          The shell sees no redirections in step 1.



          Also relevant: I'm trying to put a command in a variable, but the complex cases always fail!







          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Sep 27 at 15:08


























          community wiki





          glenn jackman























              up vote
              1
              down vote













              The bad solution is to force a double evaluation :



              eval "$TEST1"


              The good solution is to split the command semantically (url, content) :



              curl -v --silent "$url" |& grep "$content"


              Note : |& is syntactic sugar for 2>&1 |






              share|improve this answer
























                up vote
                1
                down vote













                The bad solution is to force a double evaluation :



                eval "$TEST1"


                The good solution is to split the command semantically (url, content) :



                curl -v --silent "$url" |& grep "$content"


                Note : |& is syntactic sugar for 2>&1 |






                share|improve this answer






















                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  The bad solution is to force a double evaluation :



                  eval "$TEST1"


                  The good solution is to split the command semantically (url, content) :



                  curl -v --silent "$url" |& grep "$content"


                  Note : |& is syntactic sugar for 2>&1 |






                  share|improve this answer












                  The bad solution is to force a double evaluation :



                  eval "$TEST1"


                  The good solution is to split the command semantically (url, content) :



                  curl -v --silent "$url" |& grep "$content"


                  Note : |& is syntactic sugar for 2>&1 |







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Sep 27 at 15:42









                  user285259

                  3407




                  3407



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f471842%2fio-redirection-not-working-when-command-stored-in-a-variable%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      Peggy Mitchell

                      Palaiologos

                      The Forum (Inglewood, California)