find command doesn't find directory in shell script - bash

I have a shell script that is finding and copying files, which works just fine. However when it tries to find and copy a directory it is not working
#!/bin/sh
PROJECT_NAME=$1
HELM_BUILD_FOLDER="helm-build"
HELM_PROJECT_BUILD_FOLDER="$HELM_BUILD_FOLDER/$PROJECT_NAME
#find and copy all FILES from .helm/my-project to helm-build/my-project/project-values THIS IS SUCCESSFUL
find .helm/$PROJECT_NAME* -maxdepth 0 -type f,d -exec cp -av "{}" $HELM_PROJECT_BUILD_FOLDER/project-values/ ";"
#find and copy all diectories from .helm/my-project to helm-build/my-project THIS IS FAILING even though directories exist
find .helm/$PROJECT_NAME/* -maxdepth 0 -type f -exec cp -av "{}" $HELM_PROJECT_BUILD_FOLDER/ ";"
I have tried several different means of fixing this. I've tried using execdir instead of exec, used cp -R. I tried to simply output the results of the directory find and nothing got output... it's almost as if it's not being ran.
Another weird thing is happening when i try to execute in the terminal. This works, despite $PROJECT_NAME not being defined outside of the script:
find .helm/$PROJECT_NAME/* -maxdepth 0 -type d -exec cp -R -av "{}" helm-build/my-project/ ";"

Related

bash/command line: How to copy several files in different directories at once

I am trying to copy a file (let's call it list.txt) that is in several places and give it a new name. Some folders should be ignored (e.g. those containing _old)
Assume the following structure:
/data/folder1/subfolder/user/list.txt
/data/folder2/subfolder/user/list.txt
/data/folder2/subfolder_old/user/list.txt
/data/folder3/anothername/other/list.txt
/data/folder3/anothername/ignorethisfolder/list.txt
With following command I get the exact files listed that I expect:
ll /data/*/{subfolder,anothername}/{user,other}/*.txt 2>/dev/null
That's what I want to use for copying and the following:
cp /data/*/{subfolder,anothername}/{user,other}/*.txt /data/*/{subfolder, anothername}/{user,other}/*.txt_backup 2>/dev/null
Unfortunately, this does not deliver the desired result.
What should the command for the copying process be?
Unfortunately the cp command doesn't work that way, you need to copy each file independently:
for f in /data/*/{subfolder,anothername}/{user,other}/*.txt
do
cp "$f" "${f}_backup"
done
You could use the find command:
find /data -not -path "*/*_old/*" -name "list.txt" -type f -exec cp {} {}_backup \;
Explanation
find /data traverse your /data directory
-not -path "*/*_old/*" exclude any paths with a directory ending in _old
-name "list.txt" select files/directories with the name list.txt
-type f only select files
-exec cp {} {}_backup \; execute cp on all remaining matching paths the {} is replaced with the match path and the ; is needed to end the exec statement
note
You can add your 2>/dev/null if you still get errors on some results.

Why does "find . -name somedir -exec rm -r {} \;" exit nonzero whenever it successfully deletes a directory?

I want to find a folder in a known folder but with unknown exact path, thus I must use find. When I find it, I use -exec to remove it, but I cannot evaluate if this has succeeded. Behavior somewhat confuses me; if I don't find the folder, I get return code 0:
>find . -name "testuuu" -exec rm -r {} \;
find: ‘./.docker’: Permission denied
>echo $?
0
But when I do find the folder and manage to delete it, it returns error code 1:
> find . -name "test" -exec rm -r {} \;
find: ‘./.docker’: Permission denied
find: ‘./test’: No such file or directory
> echo $?
1
Is this expected behavior? Why?
Further, how can I get return code of "rm" and not "find" and thus evaluate if the folder was deleted?
Use the -depth option to order a depth-first traversal -- that way find doesn't try to find things under your directory after the directory has already been deleted (an operation which, by nature, will always fail).
find . -depth -name "test" -exec rm -r -- '{}' \;
This option is also turned on by default when you use the -delete action in GNU find to delete content.
By the way -- if there are lots of test directories, you could get better performance by making that -exec rm -r -- {} + (which passes each copy of rm as many filenames as will fit on its command line) instead of -exec rm -r -- {} \; (which starts a new copy of rm for each test that is found), at the expense of no longer collecting individual error codes.

copying files from subfolders via grep shell script

I want to write a shell script to do the following :
I have a folder with many subfolders. Each of these subfolders has a *.gz file and some other files which I don't need. I want to move all .gz files into a new subfolder called needed_files (I have already created this subfolder). So I did the following :
I went to the parent folder with all the subfolder and cp /.gz > needed_files/., but this did not work. Can you suggest what I should be doing?
grep is irrelevant here. Use find:
find . ! \( -type d -name needed_files -prune \) -type f -name '*.gz' \
-exec echo mv -t needed_files {} +
POSIX equivalent of that -exec is
-exec sh -c 'echo mv "$#" needed_files' _ {} +
If its output looks good, remove echo.
Btw I noticed that the title says copy but you also say I want to move, so decide on what you exactly want to do and let me know so I can edit my answer.

MacOS - One line command is working in terminal but not in .sh script?

MacOS High Sierra
I have a command that I currently use in terminal:
find /private/my/tmp -mindepth 1 -maxdepth 1 -type d -not -name -specialfolder -exec rm -r {} \;
which searches the folder private/my/tmp and removes all folders except one that is named "specialfolder".
This is working perfectly from the terminal, but I cannot get it working as .sh shell script. I have used chmod +x /scripts/myscript.sh to make it executable but this has not made any difference.
The shell script is:
#!/bin/sh
find /private/my/tmp -mindepth 1 -maxdepth 1 -type d -not -name -specialfolder -exec rm -r {} \;
Running it from the terminal as "sh myscript.sh" does not produce any result, no errors, nothing.
What do I need to fix to get this to work as a .sh script?
PS - I had considered it may be a permissions issue, but I have set permissions with chmod -R 777 on the /private/my/tmp folder and still no difference.

bash script rm cannot delete folder created by php mkdir

I cannot delete folder created by php mkdir
for I in `echo $*`
do
find $I -type f -name "sess_*" -exec rm -f {} \;
find $I -type f -name "*.bak" -exec rm -f {} \;
find $I -type f -name "Thumbs.db" -exec rm -f {} \;
find $I -type f -name "error.log" -exec sh -c 'echo -n > "{}"' -f {} \;
find $I -type f -path "*/cache/*" -name "*.*" -exec rm -f {} \;
find $I -path "*/uploads/*" -exec rm -rdf {} \;
done
I want to delete under /uploads/ all files and folders please help me thanks...
You should consider changing your find command to use the -o pragma to join your conditions together as the final exec is basically the same. This will avoid recursing the file system repeatedly.
The other answers address your concern about php mkdir. I'll just add that it has nothing to do with the fact it was created with php mkdir rather than any other code or command. It is due to the ownership and permissions.
I think this is most likely because php is running in apache or another http server under a different user than you are invoking the bash script. Or perhaps the files uploaded in uploads/ are owned by the http server's user and not the user invoking it.
Make sure that you run the bash script under the same user as your http server.
To find out which user owns which file do:
ls -l
If you run you bash script as root, you should be able to delete it anyway, but that is not recommended.
Update
To run it as root for nautilus script use the following as your nautilus script:
gksudo runmydeletescript
Then put all the other code into another file with the same path as whatever you have put for runmydeletescript and run chmod +x on it. This is extremely dangerous!
You should probably add -depth to the command to delete sub-directories of upload before the directory itself.
I worry about the -path but I'm not familiar with it.
Also consider using + instead of \; to reduce the number of commands executed.

Resources