dollar sign inside eval string in bash

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












0














I have hundreds of sub-directories which contain a dollar sign (i.e., $)
as the 1st character in their names, each of which needs to be visited.
These sub-directories can not be renamed. The bash script function tries to visit each
and (so far) to echo the path its in. Trying to do this via a built path string then eval it.



The line that print cmd=$cmd indeed shows cmd=cd /rbyoko/c/$Ono.RCB as expected -
however, the eval command mis-interprets the $Ono.RCB (probably as $Ono being empty var)
and results in: -bash: cd: /rbyoko/c/.BIN/: No such file or directory
then the following line prints We are in /home/user (where the script was run from).



My question: how do I eval the string (and/or escape the sub-directory with $) to
actually succeed in visiting the desired sub-directory?



Here is my function:



visit_tree_recbin()

strings="cdhlotpw"
MACHINE=`uname -a`
PWD=`pwd`
for i in $(seq 1 $#strings)
do
c="$strings:i-1:1"
echo "Letter $i: $c"
#build eval string to do: cd "/rbyoko/$c/$Ono.RCB/"
x1="cd /rbyoko/$c/"
x2="$"
x3="Ono.RCB/"
cmd="$x1$x2$x3"
echo "cmd=$cmd"
eval "$x1$x2$x3"
echo "We are in " `pwd`
done










share|improve this question























  • Are you sure the problem isn't the assignment x2="$"? Try x2="\$" or x2='$' if you want to preserve the literal value of the backslash
    – steeldriver
    Dec 11 at 18:46










  • Yes, that's it....the x2="\$" fixed the issue, thanks !
    – BazukaJoe
    Dec 11 at 18:58










  • Note that PWD is a variable that already contains the current working directory.
    – Kusalananda
    Dec 12 at 7:51















0














I have hundreds of sub-directories which contain a dollar sign (i.e., $)
as the 1st character in their names, each of which needs to be visited.
These sub-directories can not be renamed. The bash script function tries to visit each
and (so far) to echo the path its in. Trying to do this via a built path string then eval it.



The line that print cmd=$cmd indeed shows cmd=cd /rbyoko/c/$Ono.RCB as expected -
however, the eval command mis-interprets the $Ono.RCB (probably as $Ono being empty var)
and results in: -bash: cd: /rbyoko/c/.BIN/: No such file or directory
then the following line prints We are in /home/user (where the script was run from).



My question: how do I eval the string (and/or escape the sub-directory with $) to
actually succeed in visiting the desired sub-directory?



Here is my function:



visit_tree_recbin()

strings="cdhlotpw"
MACHINE=`uname -a`
PWD=`pwd`
for i in $(seq 1 $#strings)
do
c="$strings:i-1:1"
echo "Letter $i: $c"
#build eval string to do: cd "/rbyoko/$c/$Ono.RCB/"
x1="cd /rbyoko/$c/"
x2="$"
x3="Ono.RCB/"
cmd="$x1$x2$x3"
echo "cmd=$cmd"
eval "$x1$x2$x3"
echo "We are in " `pwd`
done










share|improve this question























  • Are you sure the problem isn't the assignment x2="$"? Try x2="\$" or x2='$' if you want to preserve the literal value of the backslash
    – steeldriver
    Dec 11 at 18:46










  • Yes, that's it....the x2="\$" fixed the issue, thanks !
    – BazukaJoe
    Dec 11 at 18:58










  • Note that PWD is a variable that already contains the current working directory.
    – Kusalananda
    Dec 12 at 7:51













0












0








0







I have hundreds of sub-directories which contain a dollar sign (i.e., $)
as the 1st character in their names, each of which needs to be visited.
These sub-directories can not be renamed. The bash script function tries to visit each
and (so far) to echo the path its in. Trying to do this via a built path string then eval it.



The line that print cmd=$cmd indeed shows cmd=cd /rbyoko/c/$Ono.RCB as expected -
however, the eval command mis-interprets the $Ono.RCB (probably as $Ono being empty var)
and results in: -bash: cd: /rbyoko/c/.BIN/: No such file or directory
then the following line prints We are in /home/user (where the script was run from).



My question: how do I eval the string (and/or escape the sub-directory with $) to
actually succeed in visiting the desired sub-directory?



Here is my function:



visit_tree_recbin()

strings="cdhlotpw"
MACHINE=`uname -a`
PWD=`pwd`
for i in $(seq 1 $#strings)
do
c="$strings:i-1:1"
echo "Letter $i: $c"
#build eval string to do: cd "/rbyoko/$c/$Ono.RCB/"
x1="cd /rbyoko/$c/"
x2="$"
x3="Ono.RCB/"
cmd="$x1$x2$x3"
echo "cmd=$cmd"
eval "$x1$x2$x3"
echo "We are in " `pwd`
done










share|improve this question















I have hundreds of sub-directories which contain a dollar sign (i.e., $)
as the 1st character in their names, each of which needs to be visited.
These sub-directories can not be renamed. The bash script function tries to visit each
and (so far) to echo the path its in. Trying to do this via a built path string then eval it.



The line that print cmd=$cmd indeed shows cmd=cd /rbyoko/c/$Ono.RCB as expected -
however, the eval command mis-interprets the $Ono.RCB (probably as $Ono being empty var)
and results in: -bash: cd: /rbyoko/c/.BIN/: No such file or directory
then the following line prints We are in /home/user (where the script was run from).



My question: how do I eval the string (and/or escape the sub-directory with $) to
actually succeed in visiting the desired sub-directory?



Here is my function:



visit_tree_recbin()

strings="cdhlotpw"
MACHINE=`uname -a`
PWD=`pwd`
for i in $(seq 1 $#strings)
do
c="$strings:i-1:1"
echo "Letter $i: $c"
#build eval string to do: cd "/rbyoko/$c/$Ono.RCB/"
x1="cd /rbyoko/$c/"
x2="$"
x3="Ono.RCB/"
cmd="$x1$x2$x3"
echo "cmd=$cmd"
eval "$x1$x2$x3"
echo "We are in " `pwd`
done







bash shell-script string eval






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 12 at 8:21









ilkkachu

55.3k782150




55.3k782150










asked Dec 11 at 18:37









BazukaJoe

1




1











  • Are you sure the problem isn't the assignment x2="$"? Try x2="\$" or x2='$' if you want to preserve the literal value of the backslash
    – steeldriver
    Dec 11 at 18:46










  • Yes, that's it....the x2="\$" fixed the issue, thanks !
    – BazukaJoe
    Dec 11 at 18:58










  • Note that PWD is a variable that already contains the current working directory.
    – Kusalananda
    Dec 12 at 7:51
















  • Are you sure the problem isn't the assignment x2="$"? Try x2="\$" or x2='$' if you want to preserve the literal value of the backslash
    – steeldriver
    Dec 11 at 18:46










  • Yes, that's it....the x2="\$" fixed the issue, thanks !
    – BazukaJoe
    Dec 11 at 18:58










  • Note that PWD is a variable that already contains the current working directory.
    – Kusalananda
    Dec 12 at 7:51















Are you sure the problem isn't the assignment x2="$"? Try x2="\$" or x2='$' if you want to preserve the literal value of the backslash
– steeldriver
Dec 11 at 18:46




Are you sure the problem isn't the assignment x2="$"? Try x2="\$" or x2='$' if you want to preserve the literal value of the backslash
– steeldriver
Dec 11 at 18:46












Yes, that's it....the x2="\$" fixed the issue, thanks !
– BazukaJoe
Dec 11 at 18:58




Yes, that's it....the x2="\$" fixed the issue, thanks !
– BazukaJoe
Dec 11 at 18:58












Note that PWD is a variable that already contains the current working directory.
– Kusalananda
Dec 12 at 7:51




Note that PWD is a variable that already contains the current working directory.
– Kusalananda
Dec 12 at 7:51










1 Answer
1






active

oldest

votes


















0














Don't try run commands stored in variables (unless it's just a simple command name and/or path). It is bound to fail in interesting ways unless you get the quoting right (which can be fiddly and lead to less robust code).



In your case, it would be enough with



cd "/rbyoko/$c/$Ono.RCB"


i.e. quote the directory pathname (to allow for $c to have whitespaces) and then escape the $.



Alternatively:



cd "/rbyoko/$c"/'$Ono.RCB'


i.e. single quote the bit with the dollar sign to protect it from the shell.



Your function, modified:



visit_tree_recbin () 
for dir in c d h l o t p w; do
cd "/rbyoko/$dir"/'$Ono.RCB'
printf 'We are now in %sn' "$PWD"
done



Alternatively,



visit_tree_recbin () 
for dirpath in /rbyoko/[cdhlotpw]/'$Ono.RCB'/; do
cd "$dirpath"
printf 'We are now in %sn' "$PWD"
done



The difference is that the first variation will create directory pathnames and cd into these. This may fail if the directory does not exist.



The second variation uses a filename globbing pattern that matches existing directories. If the pattern matches anything, the cd will succeed (if you have permission to cd into the directory).



Note that bash maintains a PWD variable that contains the pathname of the current working directory, so there's no need to use pwd here.






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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    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%2f487418%2fdollar-sign-inside-eval-string-in-bash%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Don't try run commands stored in variables (unless it's just a simple command name and/or path). It is bound to fail in interesting ways unless you get the quoting right (which can be fiddly and lead to less robust code).



    In your case, it would be enough with



    cd "/rbyoko/$c/$Ono.RCB"


    i.e. quote the directory pathname (to allow for $c to have whitespaces) and then escape the $.



    Alternatively:



    cd "/rbyoko/$c"/'$Ono.RCB'


    i.e. single quote the bit with the dollar sign to protect it from the shell.



    Your function, modified:



    visit_tree_recbin () 
    for dir in c d h l o t p w; do
    cd "/rbyoko/$dir"/'$Ono.RCB'
    printf 'We are now in %sn' "$PWD"
    done



    Alternatively,



    visit_tree_recbin () 
    for dirpath in /rbyoko/[cdhlotpw]/'$Ono.RCB'/; do
    cd "$dirpath"
    printf 'We are now in %sn' "$PWD"
    done



    The difference is that the first variation will create directory pathnames and cd into these. This may fail if the directory does not exist.



    The second variation uses a filename globbing pattern that matches existing directories. If the pattern matches anything, the cd will succeed (if you have permission to cd into the directory).



    Note that bash maintains a PWD variable that contains the pathname of the current working directory, so there's no need to use pwd here.






    share|improve this answer



























      0














      Don't try run commands stored in variables (unless it's just a simple command name and/or path). It is bound to fail in interesting ways unless you get the quoting right (which can be fiddly and lead to less robust code).



      In your case, it would be enough with



      cd "/rbyoko/$c/$Ono.RCB"


      i.e. quote the directory pathname (to allow for $c to have whitespaces) and then escape the $.



      Alternatively:



      cd "/rbyoko/$c"/'$Ono.RCB'


      i.e. single quote the bit with the dollar sign to protect it from the shell.



      Your function, modified:



      visit_tree_recbin () 
      for dir in c d h l o t p w; do
      cd "/rbyoko/$dir"/'$Ono.RCB'
      printf 'We are now in %sn' "$PWD"
      done



      Alternatively,



      visit_tree_recbin () 
      for dirpath in /rbyoko/[cdhlotpw]/'$Ono.RCB'/; do
      cd "$dirpath"
      printf 'We are now in %sn' "$PWD"
      done



      The difference is that the first variation will create directory pathnames and cd into these. This may fail if the directory does not exist.



      The second variation uses a filename globbing pattern that matches existing directories. If the pattern matches anything, the cd will succeed (if you have permission to cd into the directory).



      Note that bash maintains a PWD variable that contains the pathname of the current working directory, so there's no need to use pwd here.






      share|improve this answer

























        0












        0








        0






        Don't try run commands stored in variables (unless it's just a simple command name and/or path). It is bound to fail in interesting ways unless you get the quoting right (which can be fiddly and lead to less robust code).



        In your case, it would be enough with



        cd "/rbyoko/$c/$Ono.RCB"


        i.e. quote the directory pathname (to allow for $c to have whitespaces) and then escape the $.



        Alternatively:



        cd "/rbyoko/$c"/'$Ono.RCB'


        i.e. single quote the bit with the dollar sign to protect it from the shell.



        Your function, modified:



        visit_tree_recbin () 
        for dir in c d h l o t p w; do
        cd "/rbyoko/$dir"/'$Ono.RCB'
        printf 'We are now in %sn' "$PWD"
        done



        Alternatively,



        visit_tree_recbin () 
        for dirpath in /rbyoko/[cdhlotpw]/'$Ono.RCB'/; do
        cd "$dirpath"
        printf 'We are now in %sn' "$PWD"
        done



        The difference is that the first variation will create directory pathnames and cd into these. This may fail if the directory does not exist.



        The second variation uses a filename globbing pattern that matches existing directories. If the pattern matches anything, the cd will succeed (if you have permission to cd into the directory).



        Note that bash maintains a PWD variable that contains the pathname of the current working directory, so there's no need to use pwd here.






        share|improve this answer














        Don't try run commands stored in variables (unless it's just a simple command name and/or path). It is bound to fail in interesting ways unless you get the quoting right (which can be fiddly and lead to less robust code).



        In your case, it would be enough with



        cd "/rbyoko/$c/$Ono.RCB"


        i.e. quote the directory pathname (to allow for $c to have whitespaces) and then escape the $.



        Alternatively:



        cd "/rbyoko/$c"/'$Ono.RCB'


        i.e. single quote the bit with the dollar sign to protect it from the shell.



        Your function, modified:



        visit_tree_recbin () 
        for dir in c d h l o t p w; do
        cd "/rbyoko/$dir"/'$Ono.RCB'
        printf 'We are now in %sn' "$PWD"
        done



        Alternatively,



        visit_tree_recbin () 
        for dirpath in /rbyoko/[cdhlotpw]/'$Ono.RCB'/; do
        cd "$dirpath"
        printf 'We are now in %sn' "$PWD"
        done



        The difference is that the first variation will create directory pathnames and cd into these. This may fail if the directory does not exist.



        The second variation uses a filename globbing pattern that matches existing directories. If the pattern matches anything, the cd will succeed (if you have permission to cd into the directory).



        Note that bash maintains a PWD variable that contains the pathname of the current working directory, so there's no need to use pwd here.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 12 at 9:13

























        answered Dec 12 at 8:02









        Kusalananda

        121k16228372




        121k16228372



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f487418%2fdollar-sign-inside-eval-string-in-bash%23new-answer', 'question_page');

            );

            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






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay