What does this bash script function does - bash

I am new to shell scripting and i found this function in a given script file.
##############################
# rotate_daily(filename)
rotate_daily() {
_code=0
_file_src=$1
_today=`date '+%Y-%m-%d'`
_file_dest=${_file_src}.${_today}
if [ -f ${_file_dest} ]; then
printk "rotate_daily(): ${_file_dest} already exist"
_code=1
else
if [ -f ${_file_src} ]; then
printk "rotate_daily(): ${_file_src} => ${_file_dest}"
cp -p ${_file_src} ${_file_dest}
_code=$?
>${_file_src}
fi
fi
}
I understand this is kind of coping file from one location to another location. But, it is not rotating right?. could somebody explain me what it is really does.
thanks in advance for any help

It copies _file_src to the location file_dest unless _file_dest already exists. An informative message will be printed that tells you if the file already exists or file_src_ will be copied, It also moves _file_src only if it is a file.
EDIT: forgot to mention what the command >{_file_src} does - it simply wipes out the contents of the source file. So you will have the contents of _file_src moved to file_dest in the end and _file_src will be empty. I can't figure why not simply do a move(with mv) and then create an empty file, but that's your question.

If the time stamped file already exists, this code snippet does nothing but print a message via printk indicating that. If it does not exist, it copies the source file to it and truncates the source file. I would guess that the line you are not quite understanding is:
>${_file_src}
That line truncates the original file after it has been copied. Note that there is a race condition, and any data written to the file between the copy and the truncation will be lost.

Related

Getting a "head: error reading 'path': is a directory" error

I'm trying to get the first line of a file, but for some reason, the head command seems to be called on the parent directory, which obviously won't work.
I have a variable productPath which contains the path to the file that I want to analyze. From executing an echo on that variable, I determined that the variable does indeed contain the correct path to the file I want to read. However, when I execute the following:
line = $(head -n 1 $productPath)
I get the following error:
head: error reading 'src/test/resources/features/Env_First': Is a directory
The file is actually inside the Env_First directory. I tried executing head on a few other files, and all of them seem to be doing the same thing (always trying to read the parent directory, instead of the actual file). What would be the correct usage of head to get the first line of the file?
EDIT:
As per #bhristov's request, here is a minimal reproducible snippet. Here, I'm reading a file called readableFile.feature in the directory src/test/environments.
for productPath in $(find src/test/environments -maxdepth 1)
do
echo "$productPath" #this outputs src/test/environments/readableFile.feature
line=$(head -n 1 $productPath) #this produces the error mentioned earlier
done
The find command will return the directory as the first result, which is why the error.
I suggest replacing that find with this:
for productPath in src/test/environments/*
do
echo "$productPath"
line=$(head -n 1 $productPath)
done
Another option is to add a check before doing whatever you want to do with if to see if productPath is a file.

Listing Running Processes and Sending Them to a File

my function is supposed to list all running processes and store them to process.id and if process.id exists, it should rename it to the current date with .id at the end of it, and then move it to the /logs directory. i think i have the mv and rename part working but it doesnt seem to save all of the processes to the file. do i have a syntax error on that part?
function processsaver()
{
if [ -r "process.id" ]; then
mv "process.id" logs/$(date +%d-%m-%y).id
ps -e > /process.id
fi
}
process.id and /process.id are not the same path. You probably wanted process.id or ./process.id in both places, since this kind of information really should not be in the filesystem root.

sql loader without .dat extension

Oracle's sqlldr defaults to a .dat extension. That I want to override. I don't like to rename the file. When googled get to know few answers to use . like data='fileName.' which is not working. Share your ideas, please.
Error message is fileName.dat is not found.
Sqlloder has default extension for all input files data,log,control...
data= .dat
log= .log
control = .ctl
bad =.bad
PARFILE = .par
But you have to pass filename without apostrophe and dot
sqlloder pass/user#db control=control data=data
sqloader will add extension. control.ctl data.dat
Nevertheless i do not understand why you do not want to specify extension?
You can't, at least in Unix/Linux environments. In Windows you can use the trailing period trick, specifying either INFILE 'filename.' in the control file or DATA=filename. on the command line. WIndows file name handling allows that; you can for instance do DIR filename. at a command prompt and it will list the file with no extension (as will DIR filename). But you can't do that with *nix, from a shell prompt or anywhere else.
You said you don't want to copy or rename the file. Temporarily renaming it might be the simplest solution, but as you may have a reason not to do that even briefly you could instead create a hard or soft link to the file which does have an extension, and use that link as the target instead. You could wrap that in a shell script that takes the file name argument:
# set variable from correct positional parameter; if you pass in the control
# file name or other options, this might not be $1 so adjust as needed
# if the tmeproary file won't be int he same directory, need to be full path
filename=$1
# optionally check file exists, is readable, etc. but overkill for demo
# can also check temporary file does not already exist - stop or remove
# create soft link somewhere it won't impact any other processes
ln -s ${filename} /tmp/${filename##*/}.dat
# run SQL*Loader with soft link as target
sqlldr user/password#db control=file.ctl data=/tmp/${filename##*/}.dat
# clean up
rm -f /tmp/${filename##*/}.dat
You can then call that as:
./scriptfile.sh /path/to/filename
If you can create the link in the same directory then you only need to pass the file, but if it's somewhere else - which may be necessary depending on why renaming isn't an option, and desirable either way - then you need to pass the full path of the data file so the link works. (If the temporary file will be int he same filesystem you could use a hard link, and you wouldn't have to pass the full path then either, but it's still cleaner to do so).
As you haven't shown your current command line options you may have to adjust that to take into account anything else you currently specify there rather than in the control file, particularly which positional argument is actually the data file path.
I have the same issue. I get a monthly download of reference data used in medical application and the 485 downloaded files don't have file extensions (#2gb). Unless I can load without file extensions I have to copy the files with .dat and load from there.

How do I make this if then else script

I've been trying to make this if then else script but its wrong every time.
I am brand new at this, maybe I have taken more than I can chew but I am trying to make a script that runs at launch that does this
If file exists /Users/Bob/Library/Safari/Bookmarks.plist
then do nothing
if file does not exist ( i assume this is "else") then move file from /Library/Application\ Support/Bookmarks.plist to /Users/Bob/Library/Safari/Bookmarks.plist
Any feedback is greatly appreciated, thanks in advance.
What you described could be written like that in pseudo code:
if file_exists("/Users/Bob/Library/Safari/Bookmarks.plist")
exit
if not file_exists("/Users/Bob/Library/Safari/Bookmarks.plist")
move("/Library/Application\ Support/Bookmarks.plist", "/Users/Bob/Library/Safari/Bookmarks.plist")
As you can see, the first "branch" is not really used, as you anyway plan to ignore this case.
But if we assume, that in the first case, you actually want to do something, like print a nice message, you could write it like that:
if file_exists("/Users/Bob/Library/Safari/Bookmarks.plist")
print("Nothing to do!")
else
move("/Library/Application\ Support/Bookmarks.plist", "/Users/Bob/Library/Safari/Bookmarks.plist")
As you can see, in the this example, the "else" part is equivalent to saying "if not file_exists(...)". You could also reverse the order by using "not":
if not file_exists("/Users/Bob/Library/Safari/Bookmarks.plist")
move("/Library/Application\ Support/Bookmarks.plist", "/Users/Bob/Library/Safari/Bookmarks.plist")
else
print("Nothing to do!")
DST="/Users/Bob/Library/Safari/Bookmarks.plist"
SRC="/Library/Application\ Support/Bookmarks.plist"
if [ ! -f "$DST" ]; then
mv "$SRC" "$DST"
fi
This will see if the destination exists. If not, it will move the file. Realistically there should be additional error checking, and I'm not certain a move is the best approach, since there would no longer be an "original" file.

Why won't cat work inside my bash-script?

I want to be able to display the content of my command-list document but whenever I do it just prints out "./commands.txt" but if I try the same thing outside of my script it works just fine.
This is my code:
helpFile="./commands.txt"
if [ "$com" = "help" ]
then
cat $helpFile
fi
I don't see where you get the $com variable from, but if you set it based on the first argument this should work:
#!/bin/bash
helpFile="./commands.txt"
com=$1
if [ "$com" = "help" ]
then
cat $helpFile
fi
In the above example $com will be set to the first argument passed to the script, so if you would like to display the contents of ./commands.txt you would call it like ./<script.sh> help
I'm also thinking that you should check so the file really does exists in the current working directory or perhaps try to use an absolute path i.e:
helpFile="/home/commands.txt"
I found out what was wrong. My text editor screwed up and was saving all the new edited content on the desktop instead of the folder with the script and text file. Anyways, thanks for all your help guys, I really appreciate it :)

Resources