bash script: “*.jpg” expansion not working as expected inside $(…), for picking a random filebash script to run a second command with select output from first command as variableWild card expansion that works on command line but not in a bash script

What makes an item an artifact?

Using "subway" as name for London Underground?

1980s live-action movie where individually-coloured nations on clouds fight

Pre-1972 sci-fi short story or novel: alien(?) tunnel where people try new moves and get destroyed if they're not the correct ones

Can I make plugins required?

Would the US government be able to hold control if all electronics were disabled for an indefinite amount of time?

How come the nude protesters were not arrested?

PhD - Well known professor or well known school?

Frame failure sudden death?

Project Euler #7 10001st prime in C++

Grover algorithm for a database search: where is the quantum advantage?

Is using haveibeenpwned to validate password strength rational?

Is it possible to 'live off the sea'

Arriving at the same result with the opposite hypotheses

Difference between > and >> when used with a named pipe

How does an ordinary object become radioactive?

Overlapping String-Blocks

Passing multiple files through stdin (over ssh)

Why was the Sega Genesis marketed as a 16-bit console?

Soft question: Examples where lack of mathematical rigour cause security breaches?

How is water heavier than petrol, even though its molecular weight is less than petrol?

This riddle is not to see but to solve

Déjà vu, again?

What makes Ada the language of choice for the ISS's safety-critical systems?



bash script: “*.jpg” expansion not working as expected inside $(…), for picking a random file


bash script to run a second command with select output from first command as variableWild card expansion that works on command line but not in a bash script






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2















I have a problem, with this simple script (pick a random file):



#!/usr/bin/env bash
set -x
srcDir="/home/user/Desktop/wallPapers/dir1,dir2,dir3"
randomFile=$(find "$srcDir" -type f -iname "*.jpg" | shuf -n 1)
printf '[%s]n' $randomFile
set +x


The problem is that while I can type this at the command line (and works perfectly fine):



find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg"


Then the bash debugging set-commands (set -x and +x) tells me, that for some reason bash both encloses the directory string with single quotation marks and it also replaces the double quotation marks with single quotation marks?



./script.sh
+ srcDir='/home/user/Desktop/wallPapers/dir1,dir2,dir3'
++ find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type f -iname '"*.jpg"'
find: ‘/home/user/Desktop/wallPapers/dir1,dir2,dir3’: No such file or directory
+ randomFile=
+ printf '[%s]n'
[]
+ set +x


I understand, this is what bash sees, when the script runs:



find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type -iname '*.jpg'


And this causes the "No such file or directory"-message, very very annoying... I do not understand, why it inserts these single quotation marks, I want double quotation marks used instead, just like on the command line... Could anyone please explain, I would be happy for that, thanks!










share|improve this question






























    2















    I have a problem, with this simple script (pick a random file):



    #!/usr/bin/env bash
    set -x
    srcDir="/home/user/Desktop/wallPapers/dir1,dir2,dir3"
    randomFile=$(find "$srcDir" -type f -iname "*.jpg" | shuf -n 1)
    printf '[%s]n' $randomFile
    set +x


    The problem is that while I can type this at the command line (and works perfectly fine):



    find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg"


    Then the bash debugging set-commands (set -x and +x) tells me, that for some reason bash both encloses the directory string with single quotation marks and it also replaces the double quotation marks with single quotation marks?



    ./script.sh
    + srcDir='/home/user/Desktop/wallPapers/dir1,dir2,dir3'
    ++ find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type f -iname '"*.jpg"'
    find: ‘/home/user/Desktop/wallPapers/dir1,dir2,dir3’: No such file or directory
    + randomFile=
    + printf '[%s]n'
    []
    + set +x


    I understand, this is what bash sees, when the script runs:



    find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type -iname '*.jpg'


    And this causes the "No such file or directory"-message, very very annoying... I do not understand, why it inserts these single quotation marks, I want double quotation marks used instead, just like on the command line... Could anyone please explain, I would be happy for that, thanks!










    share|improve this question


























      2












      2








      2








      I have a problem, with this simple script (pick a random file):



      #!/usr/bin/env bash
      set -x
      srcDir="/home/user/Desktop/wallPapers/dir1,dir2,dir3"
      randomFile=$(find "$srcDir" -type f -iname "*.jpg" | shuf -n 1)
      printf '[%s]n' $randomFile
      set +x


      The problem is that while I can type this at the command line (and works perfectly fine):



      find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg"


      Then the bash debugging set-commands (set -x and +x) tells me, that for some reason bash both encloses the directory string with single quotation marks and it also replaces the double quotation marks with single quotation marks?



      ./script.sh
      + srcDir='/home/user/Desktop/wallPapers/dir1,dir2,dir3'
      ++ find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type f -iname '"*.jpg"'
      find: ‘/home/user/Desktop/wallPapers/dir1,dir2,dir3’: No such file or directory
      + randomFile=
      + printf '[%s]n'
      []
      + set +x


      I understand, this is what bash sees, when the script runs:



      find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type -iname '*.jpg'


      And this causes the "No such file or directory"-message, very very annoying... I do not understand, why it inserts these single quotation marks, I want double quotation marks used instead, just like on the command line... Could anyone please explain, I would be happy for that, thanks!










      share|improve this question
















      I have a problem, with this simple script (pick a random file):



      #!/usr/bin/env bash
      set -x
      srcDir="/home/user/Desktop/wallPapers/dir1,dir2,dir3"
      randomFile=$(find "$srcDir" -type f -iname "*.jpg" | shuf -n 1)
      printf '[%s]n' $randomFile
      set +x


      The problem is that while I can type this at the command line (and works perfectly fine):



      find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg"


      Then the bash debugging set-commands (set -x and +x) tells me, that for some reason bash both encloses the directory string with single quotation marks and it also replaces the double quotation marks with single quotation marks?



      ./script.sh
      + srcDir='/home/user/Desktop/wallPapers/dir1,dir2,dir3'
      ++ find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type f -iname '"*.jpg"'
      find: ‘/home/user/Desktop/wallPapers/dir1,dir2,dir3’: No such file or directory
      + randomFile=
      + printf '[%s]n'
      []
      + set +x


      I understand, this is what bash sees, when the script runs:



      find '/home/user/Desktop/wallPapers/dir1,dir2,dir3' -type -iname '*.jpg'


      And this causes the "No such file or directory"-message, very very annoying... I do not understand, why it inserts these single quotation marks, I want double quotation marks used instead, just like on the command line... Could anyone please explain, I would be happy for that, thanks!







      command-line bash scripts






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 9 hours ago







      Okay Dokey

















      asked 9 hours ago









      Okay DokeyOkay Dokey

      409




      409




















          3 Answers
          3






          active

          oldest

          votes


















          3














          Brace expansion doesn't occur within a variable assignment, as explained here:



          Why do tilde prefixes expand prior to assignment, but braces don't



          In other contexts, the quotes would have prevented brace expansion as well.



          Even if you do manage to get srcDir to expand to a list of directories, quoting it again in the find command will cause it to be treated as a single argument instead of 3 separate paths.



          Probably the right way to do this in bash is to use an array:



          #!/usr/bin/env bash
          set -x
          srcDir=("/home/user/Desktop/wallPapers/"dir1,dir2,dir3)
          randomFile=$(find "$srcDir[@]" -type f -iname "*.jpg" | shuf -n 1)
          printf '[%s]n' "$randomFile"
          set +x





          share|improve this answer

























          • This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

            – Okay Dokey
            8 hours ago



















          2














          As others have already pointed out, the quotes are preventing the brace expansion. You could simplify your script to just:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" | shuf -n 1)"


          Or, if your file names can contain newline characters:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"


          If you want something that can run on arbitrary directories and file types, try this:



          #!/usr/bin/env bash

          targetFilePattern="$1"
          shift
          declare -a targetDirs=("$@")
          echo "find $targetDirs[@] -type f -iname '$targetFilePattern' | shuf -n 1"
          randomFile=$(find "$targetDirs[@]" -type f -iname "$targetFilePattern" | shuf -n 1)
          echo "$randomFile"


          You can then run it as:



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3


          Or even



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3,'a dir with a space'





          share|improve this answer

























          • Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

            – terdon
            8 hours ago












          • Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey see update for how to make it truly not hardcoded.

            – terdon
            7 hours ago


















          1














          Brace expansion isnt performed inside double quotes. There is a duplicate question regarding this somewhere. Also, use -printf flag for find, doing command substitution is unnecessary, so you can do this



          find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -printf '[%f]n' | shuf -n1





          share|improve this answer

























          • This breaks in the unlikely case where the file names contain newlines.

            – terdon
            8 hours ago











          • Fair point, -print0 is better for those cases

            – Sergiy Kolodyazhnyy
            8 hours ago











          • Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

            – terdon
            8 hours ago











          • @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

            – Sergiy Kolodyazhnyy
            8 hours ago











          Your Answer








          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "89"
          ;
          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: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          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%2faskubuntu.com%2fquestions%2f1148573%2fbash-script-jpg-expansion-not-working-as-expected-inside-for-pickin%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Brace expansion doesn't occur within a variable assignment, as explained here:



          Why do tilde prefixes expand prior to assignment, but braces don't



          In other contexts, the quotes would have prevented brace expansion as well.



          Even if you do manage to get srcDir to expand to a list of directories, quoting it again in the find command will cause it to be treated as a single argument instead of 3 separate paths.



          Probably the right way to do this in bash is to use an array:



          #!/usr/bin/env bash
          set -x
          srcDir=("/home/user/Desktop/wallPapers/"dir1,dir2,dir3)
          randomFile=$(find "$srcDir[@]" -type f -iname "*.jpg" | shuf -n 1)
          printf '[%s]n' "$randomFile"
          set +x





          share|improve this answer

























          • This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

            – Okay Dokey
            8 hours ago
















          3














          Brace expansion doesn't occur within a variable assignment, as explained here:



          Why do tilde prefixes expand prior to assignment, but braces don't



          In other contexts, the quotes would have prevented brace expansion as well.



          Even if you do manage to get srcDir to expand to a list of directories, quoting it again in the find command will cause it to be treated as a single argument instead of 3 separate paths.



          Probably the right way to do this in bash is to use an array:



          #!/usr/bin/env bash
          set -x
          srcDir=("/home/user/Desktop/wallPapers/"dir1,dir2,dir3)
          randomFile=$(find "$srcDir[@]" -type f -iname "*.jpg" | shuf -n 1)
          printf '[%s]n' "$randomFile"
          set +x





          share|improve this answer

























          • This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

            – Okay Dokey
            8 hours ago














          3












          3








          3







          Brace expansion doesn't occur within a variable assignment, as explained here:



          Why do tilde prefixes expand prior to assignment, but braces don't



          In other contexts, the quotes would have prevented brace expansion as well.



          Even if you do manage to get srcDir to expand to a list of directories, quoting it again in the find command will cause it to be treated as a single argument instead of 3 separate paths.



          Probably the right way to do this in bash is to use an array:



          #!/usr/bin/env bash
          set -x
          srcDir=("/home/user/Desktop/wallPapers/"dir1,dir2,dir3)
          randomFile=$(find "$srcDir[@]" -type f -iname "*.jpg" | shuf -n 1)
          printf '[%s]n' "$randomFile"
          set +x





          share|improve this answer















          Brace expansion doesn't occur within a variable assignment, as explained here:



          Why do tilde prefixes expand prior to assignment, but braces don't



          In other contexts, the quotes would have prevented brace expansion as well.



          Even if you do manage to get srcDir to expand to a list of directories, quoting it again in the find command will cause it to be treated as a single argument instead of 3 separate paths.



          Probably the right way to do this in bash is to use an array:



          #!/usr/bin/env bash
          set -x
          srcDir=("/home/user/Desktop/wallPapers/"dir1,dir2,dir3)
          randomFile=$(find "$srcDir[@]" -type f -iname "*.jpg" | shuf -n 1)
          printf '[%s]n' "$randomFile"
          set +x






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 8 hours ago

























          answered 8 hours ago









          steeldriversteeldriver

          73.6k11121197




          73.6k11121197












          • This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

            – Okay Dokey
            8 hours ago


















          • This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

            – Okay Dokey
            8 hours ago

















          This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

          – Okay Dokey
          8 hours ago






          This is exactly the solution I was looking for, thank you very much. You keep using the variables, which I wanted to learn how to use. Also, I didn't realise/knew I had to use an array, now I know in the future. In the top of my script I then define "srcDir" - and then the script does whatever it's supposed to do later on, with the result in the "randomFile"-variable. Thank you very much.

          – Okay Dokey
          8 hours ago














          2














          As others have already pointed out, the quotes are preventing the brace expansion. You could simplify your script to just:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" | shuf -n 1)"


          Or, if your file names can contain newline characters:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"


          If you want something that can run on arbitrary directories and file types, try this:



          #!/usr/bin/env bash

          targetFilePattern="$1"
          shift
          declare -a targetDirs=("$@")
          echo "find $targetDirs[@] -type f -iname '$targetFilePattern' | shuf -n 1"
          randomFile=$(find "$targetDirs[@]" -type f -iname "$targetFilePattern" | shuf -n 1)
          echo "$randomFile"


          You can then run it as:



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3


          Or even



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3,'a dir with a space'





          share|improve this answer

























          • Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

            – terdon
            8 hours ago












          • Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey see update for how to make it truly not hardcoded.

            – terdon
            7 hours ago















          2














          As others have already pointed out, the quotes are preventing the brace expansion. You could simplify your script to just:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" | shuf -n 1)"


          Or, if your file names can contain newline characters:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"


          If you want something that can run on arbitrary directories and file types, try this:



          #!/usr/bin/env bash

          targetFilePattern="$1"
          shift
          declare -a targetDirs=("$@")
          echo "find $targetDirs[@] -type f -iname '$targetFilePattern' | shuf -n 1"
          randomFile=$(find "$targetDirs[@]" -type f -iname "$targetFilePattern" | shuf -n 1)
          echo "$randomFile"


          You can then run it as:



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3


          Or even



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3,'a dir with a space'





          share|improve this answer

























          • Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

            – terdon
            8 hours ago












          • Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey see update for how to make it truly not hardcoded.

            – terdon
            7 hours ago













          2












          2








          2







          As others have already pointed out, the quotes are preventing the brace expansion. You could simplify your script to just:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" | shuf -n 1)"


          Or, if your file names can contain newline characters:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"


          If you want something that can run on arbitrary directories and file types, try this:



          #!/usr/bin/env bash

          targetFilePattern="$1"
          shift
          declare -a targetDirs=("$@")
          echo "find $targetDirs[@] -type f -iname '$targetFilePattern' | shuf -n 1"
          randomFile=$(find "$targetDirs[@]" -type f -iname "$targetFilePattern" | shuf -n 1)
          echo "$randomFile"


          You can then run it as:



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3


          Or even



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3,'a dir with a space'





          share|improve this answer















          As others have already pointed out, the quotes are preventing the brace expansion. You could simplify your script to just:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" | shuf -n 1)"


          Or, if your file names can contain newline characters:



          #!/usr/bin/env bash
          printf '[%s]n' "$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"


          If you want something that can run on arbitrary directories and file types, try this:



          #!/usr/bin/env bash

          targetFilePattern="$1"
          shift
          declare -a targetDirs=("$@")
          echo "find $targetDirs[@] -type f -iname '$targetFilePattern' | shuf -n 1"
          randomFile=$(find "$targetDirs[@]" -type f -iname "$targetFilePattern" | shuf -n 1)
          echo "$randomFile"


          You can then run it as:



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3


          Or even



          printRandomFile '*jpg' /home/terdon/Desktop/wallPapers/dir1,dir2,dir3,'a dir with a space'






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 7 hours ago

























          answered 8 hours ago









          terdonterdon

          70.1k13146230




          70.1k13146230












          • Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

            – terdon
            8 hours ago












          • Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey see update for how to make it truly not hardcoded.

            – terdon
            7 hours ago

















          • Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

            – terdon
            8 hours ago












          • Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey see update for how to make it truly not hardcoded.

            – terdon
            7 hours ago
















          Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

          – Okay Dokey
          8 hours ago





          Thanks - also this looks a bit "hardcoded" - I wanted to have the resulting random file-name in a new variable, so I could keep do some manipulation later on in the script. The prinf was only for myself, to see the value. Sorry, you, couldn't know that, because I didn't tell it before... I'm however upvoting for the good explanation, as my way of saying thanks.

          – Okay Dokey
          8 hours ago













          @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

          – terdon
          8 hours ago






          @OkayDokey if you want it in a variable, just use randomFile="$(find /home/terdon/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -print0| shuf -zn 1)"

          – terdon
          8 hours ago














          Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

          – Okay Dokey
          8 hours ago





          Yes, ok, I know. But the path is kind of "hard-coded" which is ok for a small script. But you're right. The solutions you presented are all good, thanks.

          – Okay Dokey
          8 hours ago













          @OkayDokey see update for how to make it truly not hardcoded.

          – terdon
          7 hours ago





          @OkayDokey see update for how to make it truly not hardcoded.

          – terdon
          7 hours ago











          1














          Brace expansion isnt performed inside double quotes. There is a duplicate question regarding this somewhere. Also, use -printf flag for find, doing command substitution is unnecessary, so you can do this



          find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -printf '[%f]n' | shuf -n1





          share|improve this answer

























          • This breaks in the unlikely case where the file names contain newlines.

            – terdon
            8 hours ago











          • Fair point, -print0 is better for those cases

            – Sergiy Kolodyazhnyy
            8 hours ago











          • Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

            – terdon
            8 hours ago











          • @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

            – Sergiy Kolodyazhnyy
            8 hours ago















          1














          Brace expansion isnt performed inside double quotes. There is a duplicate question regarding this somewhere. Also, use -printf flag for find, doing command substitution is unnecessary, so you can do this



          find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -printf '[%f]n' | shuf -n1





          share|improve this answer

























          • This breaks in the unlikely case where the file names contain newlines.

            – terdon
            8 hours ago











          • Fair point, -print0 is better for those cases

            – Sergiy Kolodyazhnyy
            8 hours ago











          • Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

            – terdon
            8 hours ago











          • @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

            – Sergiy Kolodyazhnyy
            8 hours ago













          1












          1








          1







          Brace expansion isnt performed inside double quotes. There is a duplicate question regarding this somewhere. Also, use -printf flag for find, doing command substitution is unnecessary, so you can do this



          find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -printf '[%f]n' | shuf -n1





          share|improve this answer















          Brace expansion isnt performed inside double quotes. There is a duplicate question regarding this somewhere. Also, use -printf flag for find, doing command substitution is unnecessary, so you can do this



          find /home/user/Desktop/wallPapers/dir1,dir2,dir3 -type f -iname "*.jpg" -printf '[%f]n' | shuf -n1






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 8 hours ago









          terdon

          70.1k13146230




          70.1k13146230










          answered 8 hours ago









          Sergiy KolodyazhnyySergiy Kolodyazhnyy

          76.3k10161337




          76.3k10161337












          • This breaks in the unlikely case where the file names contain newlines.

            – terdon
            8 hours ago











          • Fair point, -print0 is better for those cases

            – Sergiy Kolodyazhnyy
            8 hours ago











          • Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

            – terdon
            8 hours ago











          • @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

            – Sergiy Kolodyazhnyy
            8 hours ago

















          • This breaks in the unlikely case where the file names contain newlines.

            – terdon
            8 hours ago











          • Fair point, -print0 is better for those cases

            – Sergiy Kolodyazhnyy
            8 hours ago











          • Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

            – Okay Dokey
            8 hours ago











          • @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

            – terdon
            8 hours ago











          • @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

            – Sergiy Kolodyazhnyy
            8 hours ago
















          This breaks in the unlikely case where the file names contain newlines.

          – terdon
          8 hours ago





          This breaks in the unlikely case where the file names contain newlines.

          – terdon
          8 hours ago













          Fair point, -print0 is better for those cases

          – Sergiy Kolodyazhnyy
          8 hours ago





          Fair point, -print0 is better for those cases

          – Sergiy Kolodyazhnyy
          8 hours ago













          Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

          – Okay Dokey
          8 hours ago





          Thank you very much, but for a script that could eventually become bigger I prefer executing some kind of expression, based on variables, defined in the top of the script. This looks a bit more like something on the command line - but I upvoted, due to the explanation. The purpose of my script was also not to just print something out on the screen (the printf-line) - but to do some further manipulation. I know you couldn't see that from my original post, so sorry about that... And thanks.

          – Okay Dokey
          8 hours ago













          @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

          – terdon
          8 hours ago





          @OkayDokey you seem to be misunderstanding. This (and all other answers so far) are no more "hardcoded" than your approach. But perhaps we can give you better solutions if you edit your question and explain in more detail.

          – terdon
          8 hours ago













          @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

          – Sergiy Kolodyazhnyy
          8 hours ago





          @OkayDokey If you do need to use dir1,dir2,dir3 later in a script, use set command or array to save the directory names. I would explain further but currently have no time. And yes, it was not obvious that you want to reuse those further.

          – Sergiy Kolodyazhnyy
          8 hours ago

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Ask Ubuntu!


          • 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%2faskubuntu.com%2fquestions%2f1148573%2fbash-script-jpg-expansion-not-working-as-expected-inside-for-pickin%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

          Sahara Skak | Bilen | Luke uk diar | NawigatsjuunCommonskategorii: SaharaWikivoyage raisfeerer: Sahara26° N, 13° O

          The fall designs the understood secretary. Looking glass Science Shock Discovery Hot Everybody Loves Raymond Smile 곳 서비스 성실하다 Defas Kaloolon Definition: To combine or impregnate with sulphur or any of its compounds as to sulphurize caoutchouc in vulcanizing Flame colored Reason Useful Thin Help 갖다 유명하다 낙엽 장례식 Country Iron Definition: A fencer a gladiator one who exhibits his skill in the use of the sword Definition: The American black throated bunting Spiza Americana Nostalgic Needy Method to my madness 시키다 평가되다 전부 소설가 우아하다 Argument Tin Feeling Representative Gym Music Gaur Chicken 일쑤 코치 편 학생증 The harbor values the sugar. Vasagle Yammoe Enstatite Definition: Capable of being limited Road Neighborly Five Refer Built Kangaroo 비비다 Degree Release Bargain Horse 하루 형님 유교 석 동부 괴롭히다 경제력

          19. јануар Садржај Догађаји Рођења Смрти Празници и дани сећања Види још Референце Мени за навигацијуу