Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

A bash script to copy one file to multiple users UNIX
I had a co worker ask me if I knew how to copy one file into multiple users' User folders. At the High School he manages, he has atleast 3,000 users, and copying one file at a time was not an option. Of course I didnt know how to do this ... so I took on the challenge. After reading a few articles and a UNIX book, I came up with this script. Not bad for my first script.

I hope this helps someone. Any input is appreciated. I commented almost line by line for any other newbie to get started with scripting. This script will prompt the user for source filename, Users folder location, and destination (e.g. /Users/Library or /Users/Desktop). I put other features in the script; read the commented lines for explanation.


#! /bin/sh
# Alhambra Unified School District
# Manuel Plascencia 
# 10/25/2003
# Script : Copy 1 file to multiple users folders
#
# Reset Copy Counter
x=0
# Prompt for Filename and Location
echo -n "Source Filename and Location [/folder/filename.txt]: "
# Take input make it a string
read P
# If no input the take default source location
if [ "$P" = "" ]; then
P="/folder/filename.txt"
fi
# Filter Filename from $P and make a new string $N
N=`basename $P`
# Prompt for /Users/ folder location
echo -n "Where is your users folder [/Users/]: "
# Take input make it a string
read D
# If no input the take default user location
if [ "$D" = "" ]; then
G="/Users/"
D="/Users/*"
# if input then add to input /* to the end of user location
# adding /* makes a wildcard "any folder" in /user/ 
else
D=$G
D="$D/*"
fi
#
# Prompt for the destination folder 
echo -n "Where will this file be saved [/Library/Preferences/]: "
# Take input make it a string 
read L
# If no input the take default user location
if [ "$L" = "" ]; then
L="/Library/Preferences/"
fi
#
# Create Indeterminate Loop
for F in $D 
do
# Take Username from $F string 
U=`basename $F`
#
# Only if Directories is present filter
if [ -d $F ]
then
#
# copy $P to $F$L if no file exists -i prompts user for over write
# $P = Source file $F = user path 
cp -i $P $F$L
# File Copy Counter
x=`expr $x + 1`
#
# Set Owner and Group to file
# $U = user , staff = group , change group as needed
chown $U:staff $F$L$N
#
# Set File Permissions 
# 744 = 7 User: read-write-execute
#     = 4 Group: read 
#     = 4 Everyone: read
# Read = 4 , Execute = 1 , Write = 2 ,
# None = 0 , So Read+Execute+Write = 7 , Read = 4
# Set Permissions to file:
# User Read Write Execute ( rwx ) , 
# Group Read (r) , Everyone Read (r) 
chmod 744 $F$L$N
#
fi
# 
# End Loop
done
# Print Total Copied Files
echo
echo File copied $x times
echo
echo Creating Log File
echo
echo Writing to List.txt
# finds all files copied in $G | filters files with $N
# then writes file locations to List.txt
find $G -print | grep $N > List.txt
#
# Copy List.txt to Desktop
cp List.txt ~/Desktop/
# Launches TextEdit.app and opens List.txt
open ~/Desktop/List.txt
echo
echo Done
echo Enjoy
    •    
  • Currently 1.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (1 vote cast)
 
[28,394 views]  

A bash script to copy one file to multiple users | 4 comments | Create New Account
Click here to return to the 'A bash script to copy one file to multiple users' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
A bash script to copy one file to multiple users
Authored by: syko on Dec 24, '03 01:22:14PM

I wouldn't use 'cp' if you're copying Mac files with resources, etc..



[ Reply to This | # ]
A bash script to copy one file to multiple users
Authored by: kerbaugh on Dec 26, '03 02:05:03AM
   This is just a thought but you wouldn't have to worry about empty user input if you used a file input dialog, which is possible by adding a little AppleScript, like so:

thePath="$( osascript<<END
tell application "Finder"
	activate
	choose file with prompt "Choose a file to copy"
end tell

set result to (POSIX path of result as string)
END
 )"
Also, you are only getting the home directories in the /Users directory. You could query NetInfo and get home directories of all users with something like:

nireport . /users home passwd | awk '$2 ~ /../{ print $1 }'
I thought that since you were learning that you might appreciate a couple interesting variations.

[ Reply to This | # ]
might want to try perl
Authored by: b17bmbr on Dec 28, '03 03:24:44AM

i would recommend perl. for instance:

#!/usr/bin/perl

opendir LIST, "/Users";

@list=readdir LIST;

print "Enter filename\n";
$file=<>;
chomp($file);

print "enter directory\n";
$direct=<>;
chomp($direct);


chmod 0755, $file;

foreach(@list){
link $file, "/Users/".$_.$direct;
}


now, you can add a default directory, etc. i think you'll find perl a much better solution. not that i'm opposed to bash. but, let's say you want to do something like having a file updated or better yet, it is probably better, if yo have wirte access, to write a new file, especialy if it's text. take the above script and do this: (of course this assumes yo have write access to all those directories)

#!/usr/bin/perl

opendir LIST, "/Users";

@list=readdir LIST;

print "Enter filename\n";
$file=<>;
chomp($file);

print "enter directory\n";
$direct=<>;
chomp($direct);

open MSG, "/Users/user1/file.txt");
@msg=<MSG>;
close MSG;

foreach(@list){
open NEWMSG, "/Users/".$_.$direct;
print NEWMSG @msg;
close NEWMSG;
}


just a thought.



[ Reply to This | # ]
Be careful of "special" characters
Authored by: a1291762 on Dec 28, '03 08:29:22PM
One of Unix's most annoying "features" is the treatment of special characters. You should be quoting any variable that should not be broken or otherwise interpreted differntly. A file/directory with a space could cause much havoc with your script. This is the same problem Apple had with the iTunes installer fiasco. Often it's just better to use something like perl, python, tcl, [insert your favourite scripting language here] instead of shell script when you're dealing with files named by users.

FYI - I would do something like the following to copy a file into many places:

for dir in /Users/*; do cp /path/to/file "$dir"; done
Link

[ Reply to This | # ]