8

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:[email protected]/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
Kusalananda
355k42 gold badges735 silver badges1.1k bronze badges
asked Jul 6, 2018 at 6:12
4
  • Is the error output in the second box what you expected? Commented Jul 6, 2018 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 Commented Jul 6, 2018 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. Commented Jul 6, 2018 at 7:05
  • @Kusalananda added example jenkins call to question. Commented Jul 6, 2018 at 7:13

2 Answers 2

18

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:[email protected]/jenkins/job/jobname/buildWithParameters?token=ourtoken&parameter={}' \; 
answered Jul 6, 2018 at 7:19
6
  • 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 :) Commented Jan 17, 2019 at 7:52
  • @Tamás you probably don't have the ffmpeg program installed. Hence the error message ffmpeg: No such file or directory. Commented Jan 17, 2019 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. Commented Jan 17, 2019 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. Commented Jan 17, 2019 at 13:57
  • All right. Added new question here: unix.stackexchange.com/questions/495076/… Commented Jan 17, 2019 at 14:43
4

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:[email protected]/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:[email protected]/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:[email protected]/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.

answered Jul 6, 2018 at 6:30
5
  • Minor quibble: Some find releases, not some shells. Commented Jul 6, 2018 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. Commented Jul 6, 2018 at 11:30
  • @CharlesDuffy See e.g. unix.stackexchange.com/a/453198/116858 Commented Jul 6, 2018 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. Commented Jul 6, 2018 at 15:13
  • @CharlesDuffy You're right. With the quotes it'll be alright. Commented Jul 6, 2018 at 18:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.