creating a new directory each time a shell script is run on linux - linux

I'm trying to create a shell script that copies .log files from one directory to a new directory, with a new name each time the script is run.
For example lets say there's File1.log, File2.log, File3.log in /home/usr/logs
and when this script runs, I want them to be copied to a new location /home/usr/savedlogs/Run1 and the next time it runs.../home/usr/savedlog/Run2 and so on...
I'm not sure if this would be used:
cp /home/usr/logs/{File1.log,File2.log,File3.log} /home/usr/savedlogs
I'm hoping this is possible in a shell script. Thank you all for your help in advance, greatly appreciated!

Here is a simple script that might suffice your requirement:
#!/bin/bash
# Get the number of Run* directories present
newnum=$(ls -ld /home/usr/savedlogs/Run* 2>/dev/null | wc -l)
mkdir -p /home/usr/savedlogs/Run${newnum}
cp /home/usr/logs/*.log /home/usr/savedlogs/Run${newnum}
This will start from Run0 and proceeds from there

If you do not care about incrementing directory names, you can do this with a simple timestamp:
DIR=$(date +%Y%m%d%H%M%S)
mkdir $DIR
cp /home/usr/logs/FileXXX.log /home/usr/savedlogs/$DIR/
This will work as long as your copy operation happens less than once a second.

You may try with newDir=$(ls -l /home/usr/savedlogs | grep Run | wc -l) for getting the existing number of directories.
So the whole script will look like this :
newDir=$(ls -l /home/usr/savedlogs | grep Run | wc -l)
mkdir -p /home/usr/savedlogs/Run${newDir}
cp /home/usr/logs/*.log /home/usr/savedlogs/Run${newDir}
First folder will be Run0, next Run1 and so on...

Related

How to refer to variable in bash script

I have a test folder containing two files: test.txt and test2.txt. I want to copy these files from test to the test2 directory using a for loop and bsub. Here is the script I wrote, which is called looptest.sh.
looptest.sh
#!/bin/bash
cp ~/test/$F ~/test2
This is the for loop I typed in the command line:
for F in 'ls -l' ; do
bsub -n 2 -q short looptest.sh "$F" ;
done
I run the command from the test folder, but it's not working, and I think it has to do with the way I refer to "F". Any thoughts?

Using the ls command to hide non-executable files

I'm trying to have a command that will print only the non-executable files sorted by modification time in the current directory.
What I have so far is:
$ ls -lt | grep -i "...x......"
This is printing all of the files in the dir. Just starting to learn code, any help would be much appreciated.
The way to go :
for file in *; do test -x "$file" || echo "$file"; done
Thanks to not parsing ls output

Bash file that creates a directory and subdirectories

I'm new to Bash and have a little program that asks for an input between 1 and 10 and then proceeds to create the same amount of directories the user typed. At the moment my program creates all of the directories in one location, so I'm wondering if there's a way I can create a main folder and then the subdirectories inside one another.
For example:
How many directories would you like to create?
user input: 3
folder1
|-folder2
|-folder3
Any tips on how to get my program to do this will be very much appreciated.
#!/bin/bash
read -p "How many directories would you like?" num_folder
if test $num_folder -lt 10
then
for ((i=0; i<num_folder; i++)); do
mkdir folder$i
done
tree -c
read -rsp "Press enter to continue"
clear
else
echo "Please write a number between 1 and 10"
fi
Another solution maybe the usage of -p parameter with mkdir.
mkdir -p "$(seq -f "folder%0.0f" -s "/" $num_folder)"
how about:
seq 1 3 | xargs mkdir
you can simply use numbers.

Allow sh to be run from anywhere

I have been monitoring the performance of my Linux server with ioping (had some performance degradation last year). For this purpose I created a simple script:
echo $(date) | tee -a ../sb-output.log | tee -a ../iotest.txt
./ioping -c 10 . 2>&1 | tee -a ../sb-output.log | grep "requests completed in\|ioping" | grep -v "ioping statistics" | sed "s/^/IOPing I\/O\: /" | tee -a ../iotest.txt
./ioping -RD . 2>&1 | tee -a ../sb-output.log | grep "requests completed in\|ioping" | grep -v "ioping statistics" | sed "s/^/IOPing seek rate\: /" | tee -a ../iotest.txt
etc
The script calls ioping in the folder /home/bench/ioping-0.6. Then it saves the output in readable form in /home/bench/iotest.txt. It also adds the date so I can compare points in time.
Unfortunately I am no experienced programmer and this version of the script only works if you first enter the right directory (/home/bench/ioping-0.6).
I would like to call this script from anywhere. For example by calling
sh /home/bench/ioping.sh
Googling this and reading about path variables was a bit over my head. I kept up ending up with different version of
line 3: ./ioping: No such file or directory
Any thoughts on how to upgrade my scripts so that it works anywhere?
The trick is the shell's $0 variable. This is set to the path of the script.
#!/bin/sh
set -x
cd $(dirname $0)
pwd
cd ${0%/*}
pwd
If dirname isn't available for some reason, like some limited busybox distributions, you can try using shell parameter expansion tricks like the second one in my example.
Isn't it obvious? ioping is not in . so you can't use ./ioping.
Easiest solution is to set PATH to include the directory where ioping is. perhaps more robust - figure out the path to $0 and use that path as the location for ioping (assing your script sits next to ioping).
If iopinf itself depend on being ruin in a certain directory, you might have to make your script cd to the ioping directory before running.

linux checking number of files subdirectory - providing wrong variable result when subdirectory searching for does not exist

I have created a script that goes through specific subdirectories of files and tells me how many files are in each sub-directory that start with s. My problem occurs when it is searching and the sub-directory has failed to be created. For some reason, when the sub-directory that this script is searching for does not exist, it replaces the output with another previously created variable????
I am writing this in bash for linux.
I am looking at the following subdirectories...
participantdirectory/EmotMRI
participantdirectory/EmotMRI/firstfour/
participantdirectory/T1
So, this is the output I should get, when the subdirectory exists and everything is ok. It is the same for all files (if it is correct).
/home/orkney_01/jsiegel/ruth_data/participants/analysis2/1206681446/20090303/14693
16 in firstfour
776 in EmotMRI folder
2 files in T1 folder
For a directory which does not have a subdirectory created, I get this output...
bash: cd: /home/orkney_01/jsiegel/ruth_data/participants/analysis2/2102770508/20090210 /14616/EmotMRI/firstfour/: No such file or directory
/home/orkney_01/jsiegel/ruth_data/participants/analysis2/2102770508/20090210/14616
776 in firstfour
114 in EmotMRI folder
2 files in T1 folder
I think that, because firstfour is a subdirectory of EmotMRI, when firstfour folder hasn't been created, it substitutes the scan numbers in EmotMRI for this answer? The number of scans in EmotMRI (in this instance is correct). Here is my script below. If this is happening, how do I stop it from doing this?
for d in $(cat /home/orkney_01/jsiegel/ruth_data/lists/full_participant_list_location_may20)
do
if [ -d "$d" ]
then
gr="failed"
er="failed"
fr="failed"
cd $d/EmotMRI/firstfour/
gr=$(ls s*| wc -l)
echo " "
echo "$d"
echo "$gr in firstfour"
cd $d/EmotMRI/
er=$(ls s*| wc -l)
echo "$er in EmotMRI folder"
cd $d/T1/
fr=$(ls s*| wc -l)
echo "$fr files in T1 folder"
cd $d/EmotMRI
else
echo "$d is currently not available in directory"
fi
done
cd /home/orkney_01/jsiegel/ruth_data/
echo "Check complete"
I know you will probably have many improvements on this script, I am very new to linux. Thanks for your help,
Currently, you set gr to the output of ls s* | wc -l regardless of whether you successfully change your working directory. When that cd fails, it leaves you in whatever directory you were in previously.
You can combine your cd command into your other commands to set gr:
gr=$(cd $d/EmotMRI/firstfour/ && ls s* | wc -l || echo failed)
This way, if you successfully cd into the subdirectory, gr will be set to the output of the commands after &&. Otherwise, gr will be set to the output of the command after the ||. You can do the same thing with er and fr.
You are getting error messages that you shoud fix. Cd is failing because you are not allowed to change into a non-existent directory. Your shell will just stay in the directory it was in. It looks like you know how to test for directory existence, so you should just do that more to avoid trying to go into non-existent directories.

Resources