So, in my .bash_aliases file, I want to create a function that will call rm -r if I try to just call rm on a directory, and vice versa for files.
function rm() {
# What goes here?
}
I don't know if I would check if $1 is a folder/file, or something else.
rm -r is quite happy to delete non-directories.
So:
rm(){ command rm -r "$#"; }
Related
I want to download an entire website using the wget -r command and change the name of the file.
I have tried with:
wget -r -o doc.txt "http....
hoping that the OS would have automatically create file in order like doc1.txt doc2.txt but It actually save the stream of the stdout in that file.
Is there any way to do this with just one command?
Thanks!
-r tells wget to recursively get resources from a host.
-o file saves log messages to file instead of the standard error. I think that is not what you are looking for, I think it is -O file.
-O file stores the resource(s) in the given file, instead of creating a file in the current directory with the name of the resource. If used in conjunction with -r, it causes wget to store all resources concatenated to that file.
Since wget -r downloads and stores more than one file, recreating the server file tree in the local system, it has no sense to indicate the name of one file to store.
If what you want is to rename all downloaded files to match the pattern docX.txt, you can do it with a different command after wget has end:
wget -r http....
i=1
while read file
do
mv "$file" "$(dirname "$file")/doc$i.txt"
i=$(( $i + 1 ))
done < <(find . -type f)
I tried to deploy my personal blog website to my remote server recently. When I tried to move a few files and directories to another place by executing mv, some unexpected errors happened. The command line echoed "Directory not Empty". After doing some googling, I tried again with '-f' switch or '-v', the same result showed.
I logged in on the root account, and the process is here:
root#danielpan:~# shopt -s dotglob
root#danielpan:~# mv /var/www/html/wordpress/* /var/www/html
mv: cannot move `/var/www/html/wordpress/wp-content` to `/var/www/html/wp-content`:
Directory not empty
root#danielpan:~# mv -f /var/www/html/wordpress/* /var/www/html
mv: cannot move `/var/www/html/wordpress/wp-content` to `/var/www/html/wp-content`:
Directory not empty
Anybody know why?
(I'm running Ubuntu 14.04)
If You have sub-directories and "mv" is not working:
cp -R source/* destination/
rm -R source/
I found the solution finally. Because the /var/www/html/wp-content already exists, then when you try to copy /var/www/html/wordpress/wp-content there, error of Directory not Empty happens. So you need to copy /var/www/html/wordpress/wp-content/* to /var/www/html/wp-content.
Just execute this:
mv /var/www/html/wordpress/wp-content/* /var/www/html/wp-content
rmdir /var/www/html/wordpress/wp-content
rmdir /var/www/html/wordpress
Instead of copying directories by cp or rsync, I prefer
cd ${source_path}
find . -type d -exec mkdir -p ${destination_path}/{} \;
find . -type f -exec mv {} ${destination_path}/{} \;
cd $oldpwd
moves files (actually renames them) and overwrites existing ones. So it's fast enough.
But when ${source_path} contains empty subfolders you can cleanup by rm -rf ${source_path}
If I have a basic .sh file containing the following script code:
#!/bin/sh
rm -rf "MyFolder"
How do I make this running script file display results to the terminal that will indicate if the directory removal was successful?
You don't really need to make it say it was successful. You could have it say something only on error ✖, and then silence means success ✔.
That's how the Unix philosophy works:
The rule of silence, also referred to as the silence is golden rule, is an important part of the Unix philosophy that states that when a program has nothing surprising, interesting or useful to say, it should say nothing. It means that well-behaved programs should treat their users' attention and concentration as being valuable and thus perform their tasks as unobtrusively as possible. That is, silence in itself is a virtue. http://www.linfo.org/rule_of_silence.html
That's the way rm itself behaves.
If you are asking about the general case, as suggested by your question's title, you can run your script with sh -x scriptname to see what it's doing. It's also quite common to write diagnostic output into the script itself, and control it with an option.
#!/bin/sh
verbose=false
case $1 in -v | --verbose )
verbose=true
shift ;;
esac
say () {
$verbose || return
echo "$0: $#" >&2
}
say "Removing $dir ..."
rm -rf "$dir" || say "Failed."
If you run this script without any options, it will run silently, like a well-behaved Unix utility should. If you run it with the -v option, it will print some diagnostics to standard error.
rm -rf "My Folder" && echo "Done" || echo "Error!"
You can read more on creating a sequence of pipelines in bash manual
In the bash (and other similar shells) the ? environment variable gives you the exit code of the last executed command. So you can do:
#!/bin/sh
rm -rf "My Folder"
echo $?
UPDATE
If once the rm command has been executed the directory doesn't exist (because it has been successfully removed or because it didn't exist when the command was executed) the script will print 0. If the directory exists (which will mean that the command has been unable to remove it) then the script will print an exit code other than 0. If I understand properly the question this is exactly the requested behavior. If it is not, please correct me.
The previous answers was wrong : rm don't exit with error code > 0 when the dir isn't present.
Instead, I recommend to use :
dir='/path/to/dir'
if [[ -d $dir ]]; then
rm -rf "$dir"
fi
If you want rm to return a status, remove -f flag.
Example on Linux Mint (the dir doesn't exists):
$ rm -rf /tmp/sdfghjklm
$ echo $?
0
$ rm -r /tmp/sdfghjklm
$ echo $?
1
$ find /tmp/a1
/tmp/a1
/tmp/a1/b2
/tmp/a1/b1
/tmp/a1/b1/x1
simply trying
find /tmp/a1 -exec tar -cvf dirall.tar {} \;
simply doesn't work
any help
The command specified for -exec is run once for each file found. As such, you're recreating dirall.tar every time the command is run. Instead, you should pipe the output of find to tar.
find /tmp/a1 -print0 | tar --null -T- -cvf dirall.tar
Note that if you're simply using find to get a list of all the files under /tmp/a1 and not doing any sort of filtering, it's much simpler to use tar -cvf dirall.tar /tmp/a1.
You're one character away from the solution. The find command's exec option will execute the command for each file found, so you should replace -c with -r to put tar into append mode. Each time find invokes it, it'll tack on one more file:
rm -f dirall.tar
find /tmp/a1 -exec tar -rvf dirall.tar {} \;
I'd think something like "find /tmp/a1 | xargs tar cvf foo.tar" would work. But make sure you have backups first!
Does hpux have cpio ?
That will take a list of files on stdin and some versions
will write output in tar format.
I tried to remove my Git-files:
rm -R .git | yes
My CPU becomes loud, and no file is removed. I cannot understand what is going on. How can I remove my .git-files?
Try
yes | rm -r .git
You were passing the output of rm to yes (flow is left->right), but as yes does not read stdin, rm was just left hanging there.
Also, you do not really need yes anyway. As the only questions you seriously want to answer with 'yes' in an automated fashion are whether to delete read-only files, you can use the -f parameter ('force'):
rm -rf .git
.git is likely to have a lot of files under it. Try using
$ rm -Rvf .git
that way it will show you what files are being deleted.
It looks like you're trying to deal with rm asking for confirmation before each deletion by piping the output of yes, which produces and infinite number of "y" characters into rm, but you're doing it wrong.
rm -Rf .git # the -f option is "force", i.e. don't ask for confirmation.
If you want to pipe the output of one command into another, the source has to come first, before the pipe:
yes | head