-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpush_file.sh
171 lines (147 loc) · 5.6 KB
/
push_file.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env bash
########################################################################
## Title: push_file.sh
## Description: Copies a file to multiple remote machines via SCP
## Can also delete a file via SSH
## Author: Andrew Lamarra
## Dependencies: bash, ssh, sshpass
########################################################################
#------------------------------------------
# SETUP
#------------------------------------------
# Name of the file containing each hostname/IP
hosts=hosts.txt
function setup {
# Check for the required files
if [ ! -f $hosts ]; then
echo "ERROR: $hosts file not found!"
echo "Place the $hosts file in the same directory as the script."
echo " This is a list of hostnames or IPs to push the file to"
echo " Each hostname/IP should be separated by a newline"
echo " Hostnames/IPs can be commented out with a # at the start of the line"
exit 1
fi
# Total hosts
total=$(sed '/^#/d' "$hosts" | wc -l)
# Make sure sshpass is installed
if ! command -v sshpass >/dev/null; then
echo -e "sshpass not installed, installing now...\n"
sudo apt install -y sshpass || { echo -e "\nInstall failed!\n"; exit 1; }
fi
if [[ -n $delete ]]; then
del="$1"
echo "Delete option set..."
echo "File/directory to delete: $del"
else
src="$1"
echo "Local file: $src"
if [[ -z $2 ]]; then dst="$1"; else dst="$2"; fi
echo "Dest file: $dst"
fi
echo
if [[ -n $sudo ]]; then
echo -e "Sudo option set, running with elevated privileges...\n"
fi
# Get credentials for the remote account to use
read -rp "Enter the username of the remote account to use: " user
read -rp "Enter the password for $user: " -s SSHPASS
export SSHPASS
printf "\n\n"
# Clean up from previous runs of this script
rm -f completed.txt failed.txt
}
#------------------------------------------
# DISPLAY HELP
#------------------------------------------
function disp_help {
echo
echo "Copy a single file to multiple remote machines or delete a single file"
echo "NOTES:"
echo " If the file already exits on the remote machine, it will be overwritten"
echo " If using the sudo option, the destination file will be owned by the 'root' user"
echo
echo "Place the $hosts file in the same directory as the script."
echo " This is a list of hostnames or IPs to push the file to"
echo " Each hostname/IP should be separated by a newline"
echo " Hostnames/IPs can be commented out with a # at the start of the line"
echo
echo "Usage: $0 [-d|--delete] [-s|--sudo] FILE [DESTINATION]"
echo "OPTIONS:"
echo " -h|--help Display this help dialog"
echo " -d|--delete Delete the file on the remote machine (use absolute path)"
echo " -s|--sudo Pushes/deletes the file with root privileges"
echo " FILE File to copy or delete (if the -d option is set)"
echo " DESTINATION Where to save the file to on the remote machine"
echo
exit 0
}
#------------------------------------------
# EXECUTION
#------------------------------------------
function execute {
# Run through the setup
setup "$1" "$2"
# Counter for our progress indicator
i=1
while read -r host; do
printf "Progress: %3s out of $total hosts\r" "$i"
i=$((i + 1))
# Test for connectivity
ping -c1 -W1 "$host" >/dev/null 2>&1 || {
echo "$host failed ping response" >> failed.txt
continue
}
options="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
if [[ -n $delete ]]; then
if [[ -n $sudo ]]; then
echo "$SSHPASS" | sshpass -e ssh -tt $options \
"${user}@${host}" \
sudo rm -rf "$del" >/dev/null 2>&1
else
sshpass -e ssh $options \
"${user}@${host}" \
rm -rf "$del" >/dev/null 2>&1
fi
else
if [[ -n $sudo ]]; then
fname="$(echo "$src" | awk -F/ '{print $NF}')"
sshpass -e scp $options \
-r "$src" \
"${user}@${host}:~" >/dev/null 2>&1
echo "$SSHPASS" | sshpass -e ssh -tt $options \
"${user}@${host}" \
"sudo mv ~/$fname $dst; sudo chown root: $dst" >/dev/null 2>&1
else
sshpass -e scp -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-r "$src" \
"${user}@${host}:$dst" >/dev/null 2>&1
fi
fi
if [ $? -ne 0 ]; then
echo "$host failed at SSH" >> failed.txt
continue
fi
# Save hostname to a file noting this host was completed successfully
echo "$host" >> completed.txt
# Hosts can be commented out with a hash (#) at the beginning of the line
done < <(sed '/^#/d' "$hosts")
printf "\n\n"
echo "Completed."
echo "Successful hosts are saved to the 'completed.txt' file."
echo "Failed hosts are saved to the 'failed.txt' file."
echo "NOTE: These files will be overwritten upon subsequent runs of this script."
exit 0
}
# Parsing the arguments
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-h|--help ) disp_help;;
-d|--delete ) delete=true;;
-s|--sudo ) sudo=true;;
* ) execute "$1" "$2";;
esac
shift
done
disp_help