Linux command to move a directory - linux

My old and new directory have same folders and files inside.
I try:
mv -if old/* new/*
and get error
mv: cannot move `./xxxxxx' to a subdirectory of itself
How can I move it?

You should use mv -if old/* new/ without the trailing *.
This is because it unrolled to
mv -if old/foo old/bar old/baz new/foo new/bar new/baz
i.e. move everything into new/baz
This is not what you wanted.

reef#localhost:/tmp/experiment$ ls a
11 22 33
reef#localhost:/tmp/experiment$ ls b
22 33
reef#localhost:/tmp/experiment$ ls
a b
reef#localhost:/tmp/experiment$ mv a/* b
reef#localhost:/tmp/experiment$ ls a
reef#localhost:/tmp/experiment$ ls b
11 22 33
It works. What are You trying to achieve? Could You please write a short example of what the input data should look like and what the output data should look like? The truth is I have no idea what You are trying to do :) Help me help You.

note that mv a/* b/ don't move files .* (file name start with '.') in a/ to b/
ex:
$ mkdir -p a/d b && touch a/f a/.f a/d/.f
$ mv a/* b/
$ ls -a a/
. .. .f

If you are copying from an ext2/3/4 file system to a FAT32 file system, and a filename has an invalid character for FAT32 naming conventions, you get this terribly annoying and incorrect as hell error message. How do I know? I wrestled with this bug - yes, it's a KERNEL BUG - for 6 hours before it dawned on me. I thought it was a shell interpreter error, I thought it was an "mv" error - I tried multiple different shells, everything. Try this experiment: on an ext file system, "touch 'a:b'" them "mv" it to a FAT32 file system. Try it, you'll enjoy (hate) the results. The same is true for '<' and '>' (\074 and \076).
Thanks for "man mv" - that's a real big help, don't quit your day job.

Might be you got the answer but above answer is not working for me.... and finally lots of researching I got the answer. (Issue is due to files-ownership)
and just put sudo before the command and its working.... :) Same thing for cp and mv command.
sudo mv -if old/* new/

Related

Bash: unexpected behavior using a variable containing directory with escaped spaces

This is a follow up to https://apple.stackexchange.com/questions/52459/ and is about an unexpected behavior in bash. To summarize what's in that link, the problem is to copy the current directory in Terminal to a temporary variable, say the pasteboard, and use that to switch directory in a different Terminal window. The solution provided there pretty much nails it in the most efficient way! However, when I actually try changing directories using this temporary variable with the correctly escaped directory name, it seems to not work right in bash.
My minimum working example is as follows:
alias cwd='printf "%q/\n" "$(pwd)"'
Now in a terminal:
>$ mkdir tmp
>$ cd tmp
>$ mkdir test\ dir
>$ cd test\ dir
>$ cwd | pbcopy
In a new terminal:
>$ echo "$(pbpaste)"
/Users/foo/tmp/test\ dir/
>$ cd $(pbpaste)
-bash: cd: /Users/kaushik/tmp/test\: No such file or directory
>$ cd "$(pbpaste)"
-bash: cd: /Users/kaushik/tmp/test\ dir/: No such file or directory
I'm quite at loss in trying to figure out what I'm doing wrong. The only thing I'm certain of is that this is a bash problem and not something that's cropping up on OS X.
Thanks for your help on this and, by the way, it turns out that I had to finally, after all these many years, end up writing my first stack overflow post!
Copied from comments: The linked answer specifically asks for the escaped PWD suitable for pasting, but you want a programmatic input where escaping is counter-productive. Just do pwd | pbcopy and cd "$(pbpaste)".
EDIT:
(To be honest, I presumed you would need to escape it explicitly since that's how I create a directory with spaces using pwd.)
The issue is that command-line parser only does one pass of unescaping. In case of cd foo\ bar, the space is unescaped. In case of cd $(pbpaste), there is nothing to unescape; then pbpaste's literal output is put into the argument list.

When I use mv on one of my files, it disappears

When I use
mv Engine_Controls.py ~/Flight_Computer
The file disappears, but I was able to successfully move another python file without an issue into the same directory.
Also, when I type in:
sudo locate Engine_Controls.py
It says that it's in the original directory.. but it isnt.
Could somebody explain why the file is disappearing, as well as why locate says the file is still there?
edit: Problem solved.
Could you have had a typo in your mv command? Try running history | grep mv and see if you might have had a typo.
If you want to fix the 'locate' issue, try a sudo updatedb and then do your sudo locate Engine_controls.py again.
Another option would be to use the -v on the mv command. This will give you some additional info for troubleshooting. For example, if I want to move the file test to test2:
mv -v ~/test ~/test2
the output would be:
'/home/nelsone/test' -> '/home/nelsone/test2'

How to duplicate a folder exactly

I am trying to copy a filesystem for a device I am programming for. After so much time trying to figure out why the filesystem I was installing wasn't working I found out that cp didn't get the job done. I used du -s to check the size of the original filesystem and the one that I copied with cp -r, as it turns out they differ by about 150 bytes.
Something is telling me that symbolic links or some sort of kernel objects aren't being copied correctly.
Is it possible to copy a folder/file system exactly? If so how would I go about it?
Try doing this the straightforward way :
cp -a src target
from man cp
-a, --archive
same as -dR --preserve=all
It preserve rights, symlinks...
Here I tried all the code in my Linux. Seems Rsync proposed by #seanmcl as the right one while others failed to keep owners and/or some special files or a denied result. The exact code is:
$ sudo rsync -aczvAXHS --progress /var/www/html /var/www/backup
Just remember to use just the directory name and not put a slash (/) or a wildcard (/*) at the end of source and target name otherwise the hidden files right below the source are not copied.
Another popular option is to use tar c source | (cd target && tar x ). See this linuxdevcenter.com article.
The most accurate way I know of copying files is with cpio:
cd /path/to/source
find . -xdev -print0 | cpio -oa0V | (cd /path/to/target && cpio -imV)
Not really easy to use, but this is very precise, preserving timestamps, owners, permissions, special files.
Rsync is the best way to copy a file system. They are myriad arguments that let you control exactly what is copied.
This is what I do, for example to duplicate directory A -> B:
$ mkdir B
$ cd A
$ cp -a ./ ../B

Why can't I work with files in ".." from within a symbolic link?

I have the following directory structure:
misha#misha-lmd:~/tmp$ ls -l
total 4.0K
-rw-r--r-- 1 misha lmd 21 Feb 18 21:00 hello.py
lrwxrwxrwx 1 misha lmd 20 Feb 18 21:01 symlink -> /home/misha/nobackup/
Next, I try the following:
misha#misha-lmd:~/tmp$ cd symlink
misha#misha-lmd:~/tmp/symlink$ cat ../hello.py
cat: ../hello.py: No such file or directory
Why doesn't this work?
If I do this instead:
misha#misha-lmd:~/tmp/symlink$ cd ..
misha#misha-lmd:~/tmp$ cat hello.py
print "Hello World!"
Then all is well. cd handles .. properly, but cat doesn't. What is this sorcery, and how do I make things work the way I want them to?
EDIT
OK, thanks to some of the answers here, I've found out a bit more about what's going on. First, cd is not actually an executable, it is a built-in command of the shell (in this case, bash):
misha#misha-lmd:~/tmp$ type cd
cd is a shell builtin
If you man bash, you can find all about the environment variables that bash uses for its housekeeping, including moving around directories. There are other built-ins, like pwd, that have counterparts that are actually executables:
misha#misha-lmd:~/tmp/symlink$ type pwd
pwd is a shell builtin
misha#misha-lmd:~/tmp/symlink$ /bin/pwd
/home/misha/nobackup
misha#misha-lmd:~/tmp/symlink$ /bin/pwd -L
/home/misha/tmp/symlink
The /bin/pwd executable prints the physical path by default, but can also print the logical path given the `-L' switch. Similarly, when I try to do:
misha#misha-lmd:~/tmp/symlink$ cat ../hello.py
cat: ../hello.py: No such file or directory
things are failing because .. is being interpreted as the physical parent directory, not the logical one. This allows me to refine my question as:
When I specify a command-line argument to an executable, how can I get .. to mean the logical parent, not the physical one?
Because the directory .. in your symlinked directory is your home directory.
../something means "go to the .. directory", not "strip the last path component".
You can try pwd -P to see where you are, after you change into symlink.
It doesn't work because there's no /home/misha/hello.py. A symbolic link does not create a new directory, but points to the one linked. So when you cd to a symbolic link, you actually cd to that directory,
Did you expect the shell will remember from where you came from a symbolic link? Well, doesn't work like that :)
Try
cat $(cd ..; pwd)/hello.pycat
Don't know if it helps you.
EDIT:
If you really need it, here is a way to do it (but it's kind of ugly):
$ lcat ( ) ( cd "${1%/*}"; cat "${1##*/}"; )
# use it like 'cat'
$ lcat ../hello.py
Using ( ... ) instead of { ... } for the function body makes it do the cd in a sub shell instead of the current shell.
When I try it it works also with "file name completion".
But this is only solving cat, it can be more complex to use for other commands as well I think.
$ lcmd ( ) ( local cmd="$1"; shift; cd "${1%/*}"; $cmd "${1##*/}"; )
Then do e.g. lcmd cat ../hello.py

sed permission denied when overwriting file

I am trying to use sed to overwrite my index.php file, but I am getting an error:
$ sed -i 's#<head>#<head><script type="text/javascript" src="new.js"></script>#' index.php
sed: couldn't open temporary file ./sedmZNx8T: Permission denied
Does anyone know how to fix this?
Really no great answers here. Sorry if thread is dead, it came up in google searches and nothing really answered the question. Although altendky's answer is sort of the same as mine... There IS a workaround...find a world writable directory, say /tmp
cp /etc/file_to_mod /tmp
sed -i -e 's/foo/bar/g' /tmp/file_to_mod
cat /tmp/file_to_mod >/etc_file_to_mod
Hope that helps!
While editing a file in place, sed creates a temporary file, saves the result and then finally mv the original file with the temporary one.
The problem is that you don't have write permission in the directory where sed is trying to create the temp file.
As the file is /tmp/file, check the permission of the directory where you are running the command.
Seems like you have a permission issue on the /tmp dir. (as discussed bellow, you run command in phpshell, so TMP dir can be setted elsewhere than /tmp)
It should looks like :
$ ls -ld /tmp
drwxrwxrwx 333 root root 32768 12 oct. 03:13 /tmp/
explanations
When invoking sed with -i flag, sed create a temporary file in /tmp dir.
Proof with strace :
$ strace -f -e trace=file sed -i 's/a/z/' /tmp/a
execve("/bin/sed", ["sed", "-i", "s/a/z/", "/tmp/a"], [/* 94 vars */]) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
(...)
open("/tmp/sedPSBTPG", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("/tmp/sedPSBTPG", "/tmp/a") = 0
+++ exited with 0 +++
I think you can you "sudo" in front of your command. Like
sudo sed -i 's/geteuid/getppid/g' /usr/bin/vlc
It worked for me.
Given that you do not have write access to the directory where index.php is stored, then generally you would not have access to index.php...? Assuming this is a 'non-standard' case and you do have write access, sed -i is trying to create a temp file in the same directory as index.php (just checked and it is the same directory, not the CWD). Run sed without -i and end the line with something like > ~/sed.out to write the result into a file in your home directory. Then do what you will with that file.
sed 's#<head>#<head><script type="text/javascript" src="new.js"></script>#' index.php > ~/sed.out
Be aware that you while you can cp ~/sed.out index.php you can not mv ~/sed.out index.php. It would seem that cp will put the contents into index.php (not modifying the directory you do not have write permissions to) while mv tries to change the directory (that you don't have write permissions to).
check for the /tmp folder permission
It should have the following permission
drwxrwxrwt 7 root root 4.0K Nov 16 15:06 tmp
If it is not ok for you then run the following commands
sudo chown root:root /tmp
sudo chmod 1777 /tmp
once this is done, then put a sudo infront of your sed command to execute the command as a root user.
This will solve the issue
If the use of sed is not a hard requirement, you can probably use the highly ignored command ed.
ed -s index.php <<< $'%s#<head>#<head><script type="text/javascript" src="new.js"></script>#\nwq'
The <command> <<< '<my_input_string>' construct will pipe '<my_input_string>' into the <command> as standard input
The $'...' construct will be parsed for special characters. In this case the \n splits the string into two lines
You can use any construct you want to generate and pipe in the input (echo, printf, etc.)
Standard Input String:
%s#<head>#<head><script type="text/javascript" src="new.js"></script>#
wq
The first line is your regex search and replace as command for ed. The second line tells ed to write the changes and quit. You may recognize these commands from vi.
source: mrbluecoat.blogspot.com/2014/03/in-place-editing-right-way-hint-dont.html
I think there is a much easier solution. You can just print the file to the standard output and then use the sed on the stream. Afterward, you just redirect the stream to the same file. Obviously, it is a risky solution cause if you are not 100% sure that you know what you are doing you might lose the entire content of the file in question.
cat index.php | sed 's#<head>#<head><script type="text/javascript" src="new.js"></script>#' > index.php
You need to have the write permissions to the folder whose file you are changing.
As explained here: https://stackoverflow.com/a/36404569/5381704
Short answer :
$ chmod +w .
And re-run sed.
Long answer :
As already said, the problem come from the fact that you don't have write permission on . (the current directory from which you run sed). If you are on your own machine/drive then you surely can give yourself the permission to write on this directory, that's what the chmod do here, unless you want protect it for some reason. However, if your on a network drive and can't change your permission on it then you should ask the one that own the directory to do it or use a workaround solution like copy-modify-past the file somewhere else.
I had the same problem under Windows 10. I know, not the OPs question but maybe it helps other people comming from Google.
The solution for me was to remove/move the folder I am working on from the randsomeware protected folders.

Resources