Make a program USB Copyer with bash shell linux - bash

This is my code that I made to copy all fd data to the home/user directory with bash shell
#!/bin/sh
user=$(whoami)
now=$(date +"%d.%m.%Y_%H.%M.%S")
dir=$(mkdir $now) --> and here I want to create a folder as a place to copy the results according to datetime
if [ -d /media/$user/foo ]
then
echo "any media"
cp -r /media/$user /home/$user/$dir
else
echo "none of media attached"
fi
but i run thats code, cp -r /media/$user /home/$user/$dir not running as well, which is not copied to the newly created directory based on datetime , any advice ? or
something's wrong in my code ?

I suggest to replace
dir=$(mkdir $now)
with
mkdir "$now" || exit 1
dir="$now"
This will terminate your script if there is a problem with the directory creation.

Related

Bash Scripting: How to open Kate with directory and filename?

I am completely new to Bash scripting so bare with me while I try to describe this.
What I want to do be able to insert two arguments.
Arg1=Sub Folder in Documents
Arg2=Title of the text file
Using Ubuntu 20.10. (If that matters)
In short: kate ~/Documents/$Arg1/$Arg2 would be the equivalent to the command I would enter into my terminal.
The extra catch is having a keyword shortcut for the Sub Folder. For example say the Sub folder was name SUPERLONGNAME_EXTRALONG but I want a shortcut such as SHORTNAME=SUPERLONGNAME_EXTRALONG
#!/bin/sh
newfile()
dirname=$1
filename=$2
if $dirname==dir1
dirname=newdirname
fi
kate ~/Documents/$dirname/$filename
This is basically what I have now. Although as you would guess this doesn't work. (Provided for aid in seeing what I am trying to do). I can open kate within the home directory with the file name of my choice. My real issue seems to be the creating a shortcut keyword. As well as having the file save to the Document/Arg1 directory. Please help.
I run the command through terminal using
sh newfile arg1 arg2
Use an associate array shortnames to optionally translate from long to short names. Verify that file and directory exist:
#!/bin/bash
declare -A shortnames=(
[long]="short"
)
d=$1
f=$2
if [ -z "$d" ]
then
echo directory required
exit 1
fi
if [ -n "${shortnames[$d]}" ]
then
d=${shortnames[$d]}
fi
d=~/Documents/$d
if [ ! -d "$d" ]
then
echo "directory $d does not exist"
exit 1
fi
if [ -z "$f" ]
then
echo file required
exit 1
fi
kate "$d/$f"

Need help adding source dir to bash script

I am trying to run this script I found in a book:
#!/bin/bash
# copydir.sh
E_NOARGS=85
if [ -z "$1" ]
then
echo "Usage: `basename $0` directory-to-copy-to"
exit $E_NOARGS
fi
ls . | xargs -i -t cp ./{} $1
exit 0
I want to copy a text file from desktop to the home dir using this script, but every time I insert the source argument it ignores it and starts copying the whole ubuntu folder to my home dir. I am running bash on windows 10, and as I said I am a total newbie. If anyone could help and tell me how to pass the source and copy-to dir argument to this script I would be thankful.

Linux shell script to copy and rename multiple files

I have this snippet:
#!/bin/bash
parent=/parent
newfolder=/newfolder
mkdir "$newfolder"
for folder in "$parent"/*; do
if [[ -d $folder ]]; then
foldername="${folder##*/}"
for file in "$parent"/"$foldername"/*; do
filename="${file##*/}"
newfilename="$foldername"_"$filename"
cp "$file" "$newfolder"/"$newfilename"
done
fi
done
I do need to turn it around in a way that the copied files would be named after the folder they are being moved to (e.g. moving to the /root/Case22 files would be renamed to case22_1.jpg, case22_2.docx, case22_3.JPG etc). The files would be copied from USB and both destination and source directries would be entered by the user. I have written everything else and it works apart from actual renaming and thought I could adapt this snippet.
thanks
p.s. the snippet is written by Jahid and found on stackoverflow
you can try something like this;
#!/bin/bash
parent=/root
a=1
for file in $parent/Case22*; do
filename="${file%.*}"
extension="${file##*.}"
newfilename=$(printf "$filename"_"$a"."$extension")
mv -- "$file" "$newfilename"
let a=a+1
done
Thanks for the help. I have found the solution and thought I might post it here in case someone else will be looking at this.
As the title suggests I needed a Linux shell script to copy and rename multiple files keeping original directory tree (the file source and archive locations would be specified by the user of the script). Here is the code that I came up with after few days research of different sources (it includes a trap so only one instance of script would be running at a time):
lockdir=/var/tmp/mylock #directory for lock file creation
pidfile=/var/tmp/mylock/pid #directory to get the process ID number
if ( mkdir ${lockdir} ) 2> /dev/null; then #main argument to create lock file
echo $$ > $pidfile #if successful script will proceed, otherwise it will skip to the else part of the statement at the end of the script
trap 'rm -rf "$lockdir"; exit $?' INT TERM EXIT #trap to capture reasons of script termination and removal of the lock file so it could be launched again
#start of the main script body, part of successful "if" statement
# read entry_for_testing_only #request for user entry to keep script running and try to run another script instance
findir="$2/$(basename "$1")" #variable that defines final directory to which files from USB will be copied
if [ ! -d "$1" ]; then #testing if first directory entry is a valid directory’’
echo "$1" "is not a directory"
echo ""
exit
else
if [ ! -d "$2" ]; then #testing if second entry is a valid directory
echo "archive directory non existant"
exit
else
if [ -d "$findir" ] && [ "$(ls -A "$findir")" ]; then #testing if second entry directory contains the same name folders and if the folders are empty - to avoid file overwriting
echo "such folder already there and it's not empty"
exit
else
if [ ! -d "$findir" ] ; then #last archive directory argument to create final archive directory
mkdir "$findir"
else true
fi
fi
fi
fi
rsync -a "$1"/ "$findir" #command to copy all files from the source to the archive retaining the directory tree
moved_files="$(find "$findir" -type f)" #variable that finds all files that have been copied to the archive directory
for file in $moved_files; do #start of the loop that renames copied files
counter="$((counter+1))" #incrementation variable
source_name="$(basename "$1")" #variable that captures the name of the source directory
new_name="$source_name"_"$counter" #variable that puts start of the file name and incrementation element together
if echo "$file" | grep "\." #argument that captures the extension of the file
then
extension="$(echo "$file" | cut -f2 -d. )"
else
extension=
fi
full_name="$new_name"."$extension" #variable that defines the final new name of the file
dir="$(dirname "${file}")" #variable that captures the directorry address of currently looped file
mv "$file" "$dir/$full_name" #move command to rename currently looped file with the final new name
done
#end of the main script body, unsuccessful "if" statement continues here
else
echo "Another instance of this script is already running. PID: $(cat $pidfile)"
fi

Shell Script that monitors a folder for new files

I'm not a pro in shell scripting, thats why I ask here :).
Let's say I got a folder. I need a script that monitors that folder for new files (no prefix name of files is given). When a new file gets copied into that folder, another script should start. Has the second script processed the file successfully the file should be deleted.
I hope you can give me some ideas on how to achieve such script :)
Thank you very much in advance.
Thomas
Try this:
watcher.sh:
#!/bin/bash
if [ -z $1 ];
then
echo "You need to specify a dir as argument."
echo "Usage:"
echo "$0 <dir>"
exit 1
fi
while true;
do
for a in $(ls -1 $1/* 2>/dev/null);
do
otherscript $a && rm $a #calls otherscript with the file a as argument and removes it if otherscript returned something non-zero
done
sleep 2s
done
Don't forget to make it executable
chmod +x ./watcher.sh
call it with:
./watcher.sh <dirname>
try inotify(http://man7.org/linux/man-pages/man7/inotify.7.html)
or you may need to install inotify-tools (http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/) to use it by shell.

Shell script file existence on Mac issue

Ok so I have written a .sh file in Linux Ubuntu and it works perfectly. However on a Mac it always returns that the file was not found even when it is in the same directory. Can anyone help me out?
.sh file:
if [ ! -f file-3*.jar ]; then
echo "[INFO] jar could not be found."
exit
fi
Just thought I'd add, this isn't for more than one file, it's for a file that is renamed to multiple endings.
In a comment to #Paul R's answer, you said "The shell script is also in the same directory as the jar file. So they can just double click it after assigning SH files to open with terminal by default." I suspect that's the problem -- when you run a shell script by double-clicking it, it runs with the working directory set to the user's home directory, not the directory where the script's located. You can work around this by having the script cd to the directory it's in:
cd "$(dirname "$BASH_SOURCE")"
EDIT: $BASH_SOURCE is, of course, a bash extension not available in other shells. If your script can't count on running in bash, use this instead:
case "$0" in
*/*)
cd "$(dirname "$0")" ;;
*)
me="$(which "$0")"
if [ -n "$me" ]; then
cd "$(dirname "$me")"
else
echo "Can't locate script directory" >&2
exit 1
fi ;;
esac
BTW, the construct [ ! -f file-3*.jar ] makes me nervous, since it'll fail bizarrely if there's ever more than one matching file. (I know, that's not supposed to happen; but things that aren't supposed to happen have any annoying tendency to happen anyway.) I'd use this instead:
matchfiles=(file-3*.jar)
if [ ! -f "${matchfiles[0]}" ]; then
...
Again, if you can't count on bash extensions, here's an alternative that should work in any POSIX shell:
if [ ! -f "$(echo file-3*.jar)" ]; then
Note that this will fail (i.e. act as though the file didn't exist) if there's more than one match.
I think the problem lies elsewhere, as the script works as expected on Mac OS X here:
$ if [ ! -f file-3*.jar ]; then echo "[INFO] jar could not be found."; fi
[INFO] jar could not be found.
$ touch file-302.jar
$ if [ ! -f file-3*.jar ]; then echo "[INFO] jar could not be found."; fi
$
Perhaps your script is being run under the wrong shell, or in the wrong working directory ?
It's not that it doesn't work for you, it doesn't work for your users? The default shell for OS X has changed over the years (see this post) - but it looks like your comment says you have the #! in place.
Are you sure that your users have the JAR file in the right place? Perhaps it's not the script being wrong as much as it's telling you the correct answer - the required file is missing from where the script is being run.
This isn't so much an answer, as a strategy: consider some serious logging. Echo messages such as "[INFO] jar could not be found." both to the screen and to a log file, then add extra logging, such as the values of $PWD, $SHELL and $0 to the log. Then, when your customers/co-workers try to run the script and fail, they can email the log to you.
I would probably use something like
screenlog() {
echo "$*"
echo "$*" >> $LOGFILE
}
log() {
echo "$*" >> $LOGFILE
}
Define $LOGFILE at the top of your script. Then pepper your script with statements like screenlog "[INFO] jar could not be found." or log "\$PWD: $PWD".

Resources