I’m looking for a way to copy a file to all Desktops directory of each user.
Something like:
cp myfile /home/*/Desktop/
I found a way to copy files to all home directories using xargs
but it fails on the subdirectory.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityYour code expands as:
cp myfile /home/user1/Desktop/ /home/user2/Desktop/ /home/user3/Desktop/ /home/user4/Desktop/ ... /home/userN/Desktop/
From man of cp
:
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
which means, it will try to copy "myfile /home/user1/Desktop/ /home/user2/Desktop/ /home/user3/Desktop/ /home/user4/Desktop/ ..." to /home/userN/Desktop/
it will throw an error because except "myfile" all other where directories...
try this,
UserS=($(awk -F':' '{ if ( $3 >= 500 ) print $1 }' /etc/passwd))
for i in ${UserS[@]}
do
[ -d /home/"$i"/Desktop ] && cp myfile /home/"$i"/Desktop
done
for ...
command line with the wildcard expanded is less than the maximum length of the shell command line. If there is a large number of users, it might go over the limit and cause a "command line too long" error without doing anything at all. In practice, this is unlikely to be a problem unless you have a huge number of users, since the command line length might be anything from 32k bytes on Cygwin to 200k bytes on modern Linuxes.
for
will not result in a "argument list too long" error as exec()
is not called. That's only an issue when calling an external command with a great number of arguments.
Since cp
only ever takes a single destination name, you would have to make it a loop and call copy the files individually:
for destdir in /home/*/Desktop/; do
cp myfile "$destdir"
done
Using xargs
here, as you suggest, would probably work, but would be cumbersome:
printf '%s\n' /home/*/Desktop/ | xargs -I {} cp myfile {}
This relies on the names of the subdirectories under /home
not having newlines in them (but I know of no Unix that allows newlines in usernames).
It is conceivable that you'd also like to change the owner of the file to that of the owner of the corresponding Desktop
directory.
You can do this conveniently with GNU chown
(from coreutils) like so:
for destdir in /home/*/Desktop/; do
cp myfile "$destdir" &&
chown --reference="$destdir" "$destdir/myfile"
done
Doing that with xargs
:
printf '%s\n' /home/*/Desktop/ | xargs -I {} sh -c 'cp myfile "$1" && chown --reference="$1" "$1/myfile"' sh {}
cp
command looks fine. If the question is about a problem usingxargs
, you should edit the question to include both the command itself and its output (where it fails and maybe a line or two of its successes). Otherwise, the question lacks enough detail to be answerable (and is likely to be closed as unclear).cp myfile /home/*/Desktop/
won’t work because thecp
command only facilitates copying files to a single destination.