How to find -exec cd in linux / unix - linux

I'm searching for a config folder, and trying to change to that directory:
find . -name "config" -exec cd {} \;
There is one match, ./my-applications/config, but after I try this it says:
find: `cd': No such file or directory
What am I doing wrong?

The command cd is a shell built-in, not found in /bin or /usr/bin.
Of course, you can't change directory to a file and your search doesn't limit itself to directories. And the cd command would only affect the executed command, not the parent shell that executes the find command.
Use:
cd $(find . -name config -type d | sed 1q)
Note that if your directory is not found, you'll be back in your home directory when the command completes. (The sed 1q ensures you only pass one directory name to cd; the Korn shell cd takes two values on the command and does something fairly sensible, but Bash ignores the extras.)

In case you have more than one config directory:
select config in $(find . -name config -type d)
do
cd $config
break
done

find runs -exec programs as subprocesses and subprocesses cannot affect their parent process. So, it cannot be done. You may want to try
cd `find . -name "config"`

Related

Rename "*.sample.js" files to "*.js" in linux

Currently, I'm working on a project where I need to git ignore my local config files. This means that if the user clones the repository, he would see *.sample.js files inside the config dir.
If the user executes make config the following script is executed.
config: ###Misc Create config files
#cd src/backend/config
#cp cache.sample.js cache.js
#cp database.sample.js database.js
#cp steam.sample.js steam.js
#cp teamspeak.sample.js teamspeak.js
#cp website.sample.js website.js
#echo
This script basically removes the "sample" part from the file name. The above code needs to be modified when ever I add a new config file, which is not a practical thing.
I would like to convert this into a simple regex command like:
find -iname \*.sample.js -type f -exec rename -n 's/(.*sample\.js)/$1/' {} \;
This command doesn't work, at least on windows MINGW64 bash. I need a vanilla solution.
Thanks to #Jetchisel for a working solution:
find -iname '*.sample.js' -type f -exec bash -c 'for f; do cp "$f" "${f/.sample}"; done' sh {} +
Bonus: why that last + sign?
That will process as many files as possible while avoiding arg_max
as opposed to \; which will process one file per -exec call

How to find all .sh files and make them executable using bash in linux?

also when I launch I want to pass path to folder when located these .sh files
I started with this
#!/bin/bash
find /home/user_name -name "*.sh"
And after script has to write in logo list with executable files
The safest and way both in terms of security and in terms of weird file names (spaces, weird characters, and so forth) is to use find directly:
find /home/user -name "*.sh" -execdir chmod u+x {} +
You can check the comments and the manual of find why this is safe, but in short, it makes sure your file is properly quoted in the chmod command. execdir (rather then -exec) is an extra security feature making sure the command is executed in the directory the file was found in avoiding race conditions (elaborated in the manual).
another way :
find . -name "*.sh" -exec chmod ux+y {} \;
you can first check your command by using
find . -name "*.sh" -print
If you want to make all files executable for the current user, you can use the command as follows (assuming that you have permission for all files in target home folder) :
find /home/user_name -name "*.sh" -print0 | xargs -0 chmod u+x
By #kabanus command
#!/bin/bash
# chmod u+x $(find $1 -name "*.sh")
# ls -1 $1/*.sh
find $1 -name "*.sh" -print -exec chmod u+x {} +
And use as
$ ./script.sh /your_directory
/your_directory - first argument ($1) in the script.

launch several scripts located in subdirectories

Here is my problem. I have a directory that contains multiple sub-directories. In each sub-directory, there is at least one script sh.
I want to do a script that execute sequentially all this scripts.
I am pretty new to linux.
Thanks for your help,
find . -name "*.sh" -exec {} \;
This is a shell command which, beginning in the directory it's being run in (specified by .), finds file names that end in .sh and then executes those files (the found file is substituted in the {}). The backslash prevents the semicolon from being expanded by the shell (here, bash).
Try doing it using find and for:
for file in `find . -type f -name "*.sh"`; do sh $file; done
Use can also store it in array and do it:
array=($(find . -type f -name "*.sh"))
for file in ${array[#]};do sh $file; done
From the top directory, run the following command:
for f in `find . -type f -name \*.sh`; do $f; done
The find command will locate all .sh files. The output of the find command (a whitespace separated list of pathnames to the scripts) becomes the input to the for command. The for command processes each input, assigning each entry to the variable f. The "$f" executes each script.

Run an Executable Program File in Multiple Subdirectories Using Shell

I have a main directory with 361 subdirectories. Within the each subdirectory, there is a parameter file and one executable program file. The executable file is coded to look for the parameter file in the directory where the executable is located. (The same executable file is in all subdirectories. The parameter files all have the same file name in all subdirectories)
Instead of executing the program file individually, is there a cshell command for terminal to run them all at once?
UPDATED
If your Linux is so old it doesn't have -execdir, you could try this:
find $(pwd) -name YourProgram -exec dirname {} \; | while read d; do cd "$d" && pwd; done
If that correctly prints the names of the directories where your program needs to be run, just remove the pwd and replace with whatever you want done in tha directory - presumably something like this:
find $(pwd) -name YourProgram -exec dirname {} \; | while read d; do cd "$d" && ./YourPrgram; done
ORIGINAL ANSWER
Like this maybe:
find . -type f -name YourProgramName -execdir ./YourProgramName YourParameterFile \;
But backup first and check it looks right before using.
The -execdir causes find to change to the directory it has found before running the commands there.
If your command is more complicated, you can do this:
find . -type f -name YourProgramName -execdir sh -c "command1; command2; command3" \;
Check it does what you want like this:
find . -type f -name YourProgramName -execdir pwd \;
Maybe this will help. Suppose you have in each folder a file named params_file and an executable named exec_file, then:
for dir in `find . -maxdepth 1 -mindepth 1 -type d` ; do
cd $dir
cat params_file | xargs ./exec_file
cd ..
done

Find -exec and Bash scripts

I'm writing a script in bash.
I invoke it with
find *.zip -type f -exec ./myscript.sh {} \;
At the top of my script I invoke another script like this:
#!/bin/bash
. ticktick.sh
I get the following error
.: ticktick.sh: file not found
If I invoke the script like this
./myscript.sh somefile.zip
it works
If I put the ticktick.sh script in my path in another directory it breaks, so that isn't an option. Is there some special kind of context that scripts called with a find have? I'm obviously new to BASH scripting. Any help would be appreciated
I think there are 2 problems.
1.: if you want to search for all zip files in the current directory, you have to write the following command
find . -type f -name *.zip -exec ...
2.: you execute myscript.sh with ./ before it. So myscript.sh has to be in the current working directory. if your script is in /home/jd/ and you execute it from /home/ your myscript.sh will be not found.
first you have to determine the directory of your files:
install_path=$(dirname $(readlink -f $0))
So your complete find command is:
find . -type f -name *.zip -exec $install_path/myscript.sh {} \;
The myscript.sh file have to be in the same directory as ticktick.sh

Resources