Combining if/else with variables in find command in bash script











up vote
0
down vote

favorite












I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?










share|improve this question
























  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    2 days ago










  • Related: But what if …?
    – Scott
    2 days ago















up vote
0
down vote

favorite












I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?










share|improve this question
























  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    2 days ago










  • Related: But what if …?
    – Scott
    2 days ago













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?










share|improve this question















I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?







bash find






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago









ilkkachu

53.7k781146




53.7k781146










asked 2 days ago









kerrin

1013




1013












  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    2 days ago










  • Related: But what if …?
    – Scott
    2 days ago


















  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    2 days ago










  • Related: But what if …?
    – Scott
    2 days ago
















Related - How can I expand a quoted variable to nothing if it's empty?
– roaima
2 days ago




Related - How can I expand a quoted variable to nothing if it's empty?
– roaima
2 days ago












Related: But what if …?
– Scott
2 days ago




Related: But what if …?
– Scott
2 days ago










1 Answer
1






active

oldest

votes

















up vote
2
down vote













You can deal with the symlink with a simple variable:



symlink_flag=
if [[ $symlink_boolean == y ]]; then
symlink_flag=-L
fi
find $symlink_flag "$location" -maxdepth "$depth" -readable ...


Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



For the depth part, your best bet is to build the command line in an array:



arguments=()
if [[ $symlink_boolean == y ]]; then
arguments+=(-L)
fi
arguments+=("$location")
if [[ $depth_boolean == y ]]; then
arguments+=(-maxdepth "$depth")
fi
find "${arguments[@]}" -readable -iname ...


You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "${arguments[@]}".



See also:




  • How can we run a command stored in a variable?


  • Word Splitting in BashGuide

  • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"




Technically, you can also do what you propose with command substitution:



find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
$(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.





As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






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: 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%2f482499%2fcombining-if-else-with-variables-in-find-command-in-bash-script%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








    up vote
    2
    down vote













    You can deal with the symlink with a simple variable:



    symlink_flag=
    if [[ $symlink_boolean == y ]]; then
    symlink_flag=-L
    fi
    find $symlink_flag "$location" -maxdepth "$depth" -readable ...


    Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



    For the depth part, your best bet is to build the command line in an array:



    arguments=()
    if [[ $symlink_boolean == y ]]; then
    arguments+=(-L)
    fi
    arguments+=("$location")
    if [[ $depth_boolean == y ]]; then
    arguments+=(-maxdepth "$depth")
    fi
    find "${arguments[@]}" -readable -iname ...


    You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "${arguments[@]}".



    See also:




    • How can we run a command stored in a variable?


    • Word Splitting in BashGuide

    • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"




    Technically, you can also do what you propose with command substitution:



    find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
    $(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


    Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.





    As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






    share|improve this answer



























      up vote
      2
      down vote













      You can deal with the symlink with a simple variable:



      symlink_flag=
      if [[ $symlink_boolean == y ]]; then
      symlink_flag=-L
      fi
      find $symlink_flag "$location" -maxdepth "$depth" -readable ...


      Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



      For the depth part, your best bet is to build the command line in an array:



      arguments=()
      if [[ $symlink_boolean == y ]]; then
      arguments+=(-L)
      fi
      arguments+=("$location")
      if [[ $depth_boolean == y ]]; then
      arguments+=(-maxdepth "$depth")
      fi
      find "${arguments[@]}" -readable -iname ...


      You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "${arguments[@]}".



      See also:




      • How can we run a command stored in a variable?


      • Word Splitting in BashGuide

      • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"




      Technically, you can also do what you propose with command substitution:



      find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
      $(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


      Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.





      As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






      share|improve this answer

























        up vote
        2
        down vote










        up vote
        2
        down vote









        You can deal with the symlink with a simple variable:



        symlink_flag=
        if [[ $symlink_boolean == y ]]; then
        symlink_flag=-L
        fi
        find $symlink_flag "$location" -maxdepth "$depth" -readable ...


        Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



        For the depth part, your best bet is to build the command line in an array:



        arguments=()
        if [[ $symlink_boolean == y ]]; then
        arguments+=(-L)
        fi
        arguments+=("$location")
        if [[ $depth_boolean == y ]]; then
        arguments+=(-maxdepth "$depth")
        fi
        find "${arguments[@]}" -readable -iname ...


        You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "${arguments[@]}".



        See also:




        • How can we run a command stored in a variable?


        • Word Splitting in BashGuide

        • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"




        Technically, you can also do what you propose with command substitution:



        find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
        $(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


        Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.





        As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






        share|improve this answer














        You can deal with the symlink with a simple variable:



        symlink_flag=
        if [[ $symlink_boolean == y ]]; then
        symlink_flag=-L
        fi
        find $symlink_flag "$location" -maxdepth "$depth" -readable ...


        Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



        For the depth part, your best bet is to build the command line in an array:



        arguments=()
        if [[ $symlink_boolean == y ]]; then
        arguments+=(-L)
        fi
        arguments+=("$location")
        if [[ $depth_boolean == y ]]; then
        arguments+=(-maxdepth "$depth")
        fi
        find "${arguments[@]}" -readable -iname ...


        You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "${arguments[@]}".



        See also:




        • How can we run a command stored in a variable?


        • Word Splitting in BashGuide

        • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"




        Technically, you can also do what you propose with command substitution:



        find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
        $(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


        Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.





        As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 2 days ago

























        answered 2 days ago









        ilkkachu

        53.7k781146




        53.7k781146






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482499%2fcombining-if-else-with-variables-in-find-command-in-bash-script%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

            Entries order in /etc/network/interfaces

            新発田市

            Grub takes very long (several minutes) to open Menu (in Multi-Boot-System)