4

I have a bunch of folders which have a subfolder somewhere called 360.

find . -name '360' -type d -exec 'echo "{}"' \;

output:

find: echo "./workspace/6875538616c6/raw/2850cd9cf25b/360": No such file or directory

For each found item, I want to do a curl call, and trigger a Jenkins build job. My problem is that ./ part at the start. I should be able to cut it off like this:

find . -name '360' -type d -exec 'echo {} | cut -c 2-' \;

But because it starts with a ./ it will just be executed ("No such file or directory"). How can I get the output from find, without the leading ./?

update:

Here is the whole thing with a jenkins curl call:

find reallylongfolderstructure -name '360' -type d -exec 'curl http://user:token@ourdomain.net/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter={}' \; 

output

08:53:52 find: ‘curl http://user:token@ourdomain/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter=reallylongfolderstructure/something/lol/360’: No such file or directory
  • Is the error output in the second box what you expected? – Michael Homer Jul 6 '18 at 6:32
  • no. I just guessed, it's because of the trailing ./ . What Kusalanada wrote actually helped with the trailing ./, but I'm still getting the same error. No such file or directory – Tamás Jul 6 '18 at 6:57
  • @Tamás You probably didn't use the code I wrote exactly as I wrote it. If you show how you trigger the Jenkins build, I could also show how to do that directly from find. – Kusalananda Jul 6 '18 at 7:05
  • @Kusalananda added example jenkins call to question. – Tamás Jul 6 '18 at 7:13
8

You write

because it starts with a ./ it will just be executed ("No such file or directory").

This isn't what's happening. You have provided a single command to the find ... -exec parameter of echo "{}". Note that this is not echo and the directory found by find; it's a single command that includes a space in its name. The find command (quite reasonably) cannot execute a command called echo "./workspace/6875538616c6/raw/2850cd9cf25b/360".

Remove the single quotes around the -exec parameter and you may find you don't need any additional changes or workarounds:

find . -name '360' -type d -exec echo "{}" \;

Similarly here you need to remove the quoting of the entire value passed to -exec. But in this case you still need to quote the storage arguments so the shell cannot interpret &, etc.

find reallylongfolderstructure -name '360' -type d -exec curl 'http://user:token@ourdomain.net/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter={}' \; 
  • I'm trying to do something similiar and it's not working. find $WORKSPACE -name "*.mp4" -exec ffmpeg -i {} -qscale:v 1 -vf fps=6 {}_exportedFrame_%d.jpg \; find: ffmpeg: No such file or directory Maybe you can help me out again :) – Tamás Jan 17 at 7:52
  • @Tamás you probably don't have the ffmpeg program installed. Hence the error message ffmpeg: No such file or directory. – roaima Jan 17 at 9:20
  • I do have it installed. I just get this error when I execute the shell command from a jenkins(mac build slave) build job. Executing the same command from the terminal works fine. – Tamás Jan 17 at 10:05
  • @Tamás in that case I suggest you ask a fresh question. Reference this one - or my answer - if it helps provide context. – roaima Jan 17 at 13:57
  • All right. Added new question here: unix.stackexchange.com/questions/495076/… – Tamás Jan 17 at 14:43
2

The issue is you are quoting both the utility name and the argument as a single string, which causes find to try to execute the whole thing as the name of the command.

Instead use

find . -type d -name '360' -exec curl "http://user:token@ourdomain.net/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter={}" ';' 

In some older implementations of find, {} won't be recognized as the pathname that find has found when it's concatenated with another string as above, and you would have to use a child shell instead:

With your call to curl:

find -type d -name '360' -exec sh -c '
    for pathname do
        curl "http://user:token@ourdomain.net/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter=$pathname"
    done' sh {} +

See also:


In bash:

shopt -s globstar

for pathname in ./**/360/; do
    curl "http://user:token@ourdomain.net/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter=$pathname"
done

The globstar shell option makes the ** glob pattern available. It works like *, but matches across slashes in pathnames.

  • Minor quibble: Some find releases, not some shells. – Charles Duffy Jul 6 '18 at 11:27
  • @CharlesDuffy Well OK, I'll add that (as soon as I get to a computer). The csh shell will mess up if concatenating {} with a string, and that's the only current issue that I've seen anyone have recently. That's why I only mentioned shells. – Kusalananda Jul 6 '18 at 11:30
  • @CharlesDuffy See e.g. unix.stackexchange.com/a/453198/116858 – Kusalananda Jul 6 '18 at 12:17
  • That's an issue in tcsh only without adequate quoting (AIUI, csh not my strength); with the quotes in your code it'd be fine. Re: the find end of things, quoting from the spec: If a utility_name or argument string contains the two characters "{}", but not just the two characters "{}", it is implementation-defined whether find replaces those two characters or uses the string without change. – Charles Duffy Jul 6 '18 at 15:13
  • @CharlesDuffy You're right. With the quotes it'll be alright. – Kusalananda Jul 6 '18 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.