Help - Bash Script


 
Thread Tools Search this Thread
Top Forums UNIX for Beginners Questions & Answers Help - Bash Script
# 1  
Old 05-22-2019
Help - Bash Script

Hi All, is there someone that can help me to understand this short code:
Code:
ls ${BACKUPS_FOLDER} | egrep "$(date +%Y -d "${i} year ago")-[0-9]{2}-[0-9]{2}" |sort -u | head n- 1

In particular, I would know the meaning of the part ...-[0-9]{2}-[0-9]{2} | sort -u | head -n 1.
Thanks in advance.
Stefano

Last edited by Scrutinizer; 05-22-2019 at 07:44 PM..
# 2  
Old 05-22-2019
Quote:
Originally Posted by Stefano
Hi All, is there someone that can help me to understand this short code:
Code:
ls ${BACKUPS_FOLDER} | egrep "$(date +%Y -d "${i} year ago")-[0-9]{2}-[0-9]{2}" |sort -u | head n- 1

In particular, I would know the meaning of the part ...-[0-9]{2}-[0-9]{2} | sort -u | head -n 1.
Thanks in advance.
Stefano
Hi Stefano,
What operating system are you using?

What version of the date utility are you using?

The command head n- 1 in your pipeline is always going to give you an error unless you have two files in your current working directory named n- and 1. I assume that you intended to write head -n 1 instead of head n- 1.

The meaning of the date -d option varies depending on the operating system you're using and the version of date you're using.

I would guess that the code is attempting to print the name of the last file in the directory named by the contents of the BACKUPS_FOLDER variable whose name contains a date of the form YYYY-MM-DD where YYYY is last year. Whether or not it succeeds will depend on the answers to the questions above and the names of the files in that directory.
This User Gave Thanks to Don Cragun For This Post:
# 3  
Old 05-25-2019
Hi Don and thank you so much for answer. I solved. The code posted is used, in that case, as a regular expression for a date in the format YYYY-MM-DD where YYYY is the current year, less the value of the variable {i}.

But now, I have one other issue very very difficult to understand (for me, naturally).

I would know what does mean this code
Code:
ls ${BACKUPDIR} | grep -v -e "$(echo -n $(listUniqueBackups) | sed "s//\\\|g")"

...
... in particular the two sections | grep -v -e "$echo -n ... and ... sed "s//\\\|g"

Thanks in advance.

PS The code is a command of linux bash script !

Last edited by Scrutinizer; 05-25-2019 at 12:17 PM.. Reason: code tags
# 4  
Old 05-25-2019
Quote:
Originally Posted by Stefano
Hi Don and thank you so much for answer. I solved. The code posted is used, in that case, as a regular expression for a date in the format YYYY-MM-DD where YYYY is the current year, less the value of the variable {i}.

But now, I have one other issue very very difficult to understand (for me, naturally).

I would know what does mean this code
Code:
ls ${BACKUPDIR} | grep -v -e "$(echo -n $(listUniqueBackups) | sed "s//\\\|g")"

...
... in particular the two sections | grep -v -e "$echo -n ... and ... sed "s//\\\|g"

Thanks in advance.

PS The code is a command of linux bash script !
I don't have access to a Linux system to test this out, but I would expect the sed command at the end of the pipeline in your command substitution to fail due to a missing search pattern or a missing replacement pattern terminator. Are you sure you showed us the exact command that is being used?

On a standards conforming system, using echo -n output as input to sed would produced unspecified results, but processing an incomplete line of input might work with a GNU sed utility.

If you want our help with puzzles like this, please show us the relevant input variable contents (e.g. $BACKUPDIR and $listUniqueBackups).

In this case, please also show us all of the output produced when you run the command:
Code:
echo -n $(listUniqueBackups) | sed "s//\\\|g"

# 5  
Old 05-25-2019
Hi Don, belove the full text of a bash script I would use to manage a daily incremetal backup and delete the old ones. It should list - one after the other - Yearly, Montly, Weekly and Daily backups; after that, it should produce an unique total backups and, at the end, a list of backups to delete.
In the code I do not understand the final part; in particular:

Code:
ls ${CARTELLA_BACKUPS} | grep -v -e "$(echo -n "$(ListaBackupsUnica)" | sed "s//\\\|/g")"

and
Code:
BackupsDaCancellare | while read file_da_cancellare; do
rm -rf ${file_da_cancellare}

I have not still runned the code (so i can't show the output) because, first, I prefer realize what I am doing and mostly because I don't want mess up something!

Here is the total code (the variables and functions are expressed in Italy idioma):

Code:
#!/bin/bash
CARTELLA_BACKUPS=/mnt/BACKUP/
function ListaBackupsAnnui() {
for i in 0 1 2 3 4 5
do ls ${CARTELLA_BACKUPS} | egrep "$[0-9]{2}.[0-9]{2}.(date +%Y -d "${i} year ago")" | sort -u | head -n 1
done
}

function ListaBackupsMensili() {
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12
do ls ${CARTELLA_BACKUPS} | egrep "$[0-9]{2}.(date +%m -d "${i} month ago".%Y)" | sort -u | head -n 1
done
}

function ListaBackupsSettimanali() {
for i in 0 1 2 3 4
do ls ${CARTELLA_BACKUPS} | grep "$(date +%d -d "last monday -${i} weeks".%m.%Y)"
done
}

function ListaBackupsGiornalieri() {
for i in 0 1 2 3 4 5 6
do ls ${CARTELLA_BACKUPS} | grep "$(date +%d -d "-${i} day".%m.%Y)"
done
}

function ElencoComplessivo() {
ListaBackupsAnnui
ListaBackupsMensili
ListaBackupsSettimanali
ListaBackupGiornalieri
}

function ListaBackupsUnica() {
ElencoComplessivo | sort -u
}

function BackupsDaCancellare() {
ls ${CARTELLA_BACKUPS} | grep -v -e "$(echo -n "$(ListaBackupsUnica)" | sed "s//\\\|/g")"
}

cd ${CARTELLA_BACKUPS}
BackupsDaCancellare | while read file_da_cancellare; do
rm -rf ${file_da_cancellare}
done


Last edited by Neo; 05-26-2019 at 10:17 AM..
# 6  
Old 05-25-2019
Note that using yellow text on a white or gray background produces text that is almost invisible to an old guy like me with glaucoma.

Note that when you ask how a segment of code is going to behave, failing to EXACTLY copy the code about which you have questions wastes everybody's time (especially yours).

Note that when trying to get some code working, you usually NEED to set up a test bed where you have files with similar (preferably identical) names in file hierarchies that mimic the file hierarchies your script will be processing. For example, your script looks at files in the directory named by the variable CARTELLA_BACKUPS. Set up a copy of the files in that directory in another directory and change the way CARTELLA_BACKUPS is set to point to your test bed copy of those files while you are debugging your script. That way you can run your code and see what it does and not have to worry about destroying anything.

The shell's set -xv command is your friend when trying to figure out what code is doing. Once you issue that command, every command bash executes after that will be copied to your script's standard error output with all of the variables expanded so you (and us, if you need our help) can see clearly what the shell is trying to do for you.

Note that the on-line manual pages for your system are your friends too. The command man sed will display the manual page for sed on your system so you can read all about what it is supposed to do. If you look at the sed manual page you will find that the command I asked you to run:
Code:
echo -n $(listUniqueBackups) | sed "s//\\\|g"

will NEVER destroy anything in any file unless you redirect its output to a file or invoke it with the -i option (neither of which is the case here).

When I run that command on my system running macOS Mojave (version 10.14.5) without creating a function or utility named listUniqueBackups first, bash prints the diagnostic messages:
Code:
sed: 1: "s//\\|g": unterminated substitute in regular expression
bash: listUniqueBackups: command not found

If we use the real command that is in your script instead of the code you asked us about in post #3 in this thread and I feed it a fixed string containing a <newline> character, then I get the diagnostic message:
Code:
 echo a b c | sed "s//\\\|/g"
sed: first RE may not be empty

Maybe you'll get a similar diagnostic and you'll know that you have to actually supply an RE for sed to match. Maybe your version of sed will assign some meaning to an initial search for the empty RE (which is not mentioned on the Linux 2.6 commands sed man page and we'll be able to figure out what it is that it does, if you run the command and show us the output. If you're not willing to help me figure out how utilities behave on your system, then I'm afraid there is nothing I can do to help you.

Also note that if you change the line in your complete script:
Code:
rm -rf ${file_da_cancellare}

to:
Code:
echo rm -rf ${file_da_cancellare}

there won't be anything in your script that creates or removes any permanent files. It will be perfectly safe to run without even setting up a shadow file hierarchy.

Have you tried asking the person who gave you this code how the pieces of it that you don't understand are supposed to work?

Last edited by Don Cragun; 07-24-2019 at 04:12 PM.. Reason: Fix typo: s/cataracts/glaucoma/
# 7  
Old 05-26-2019
Quote:
Originally Posted by Don Cragun
Note that using yellow text on a white or gray background produces text that is almost invisible to an old guy like me with cataracts.
Hi Don,

I changed the colors added by the original poster to black.

Hope that helps!
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

In Bash shell - the ps -ef shows only the /bin/bash but the script name is not displayed

In Bash shell - the ps -ef shows only the /bin/bash but the script name is not displayed ? Is there any way to get the script names for the process command ? --- Post updated at 08:39 AM --- in KSH (Korn Shell), my command output shows the script names but when run in the Bash Shell... (3 Replies)
Discussion started by: i4ismail
3 Replies

2. Shell Programming and Scripting

How to block first bash script until second bash script script launches web server/site?

I'm new to utilities like socat and netcat and I'm not clear if they will do what I need. I have a "compileDeployStartWebServer.sh" script and a "StartBrowser.sh" script that are started by emacs/elisp at the same time in two different processes. I'm using Cygwin bash on Windows 10. My... (3 Replies)
Discussion started by: siegfried
3 Replies

3. Shell Programming and Scripting

Different behavior between bash shell and bash script for cmd

So I'm trying to pass certain json elements as env vars and use them later on in a script. Sample json: JSON='{ "Element1": "file-123456", "Element2": "Name, of, company written in, a very weird way", "Element3": "path/to/some/file.txt", }' (part of the) script: for s... (5 Replies)
Discussion started by: da1
5 Replies

4. Shell Programming and Scripting

Make a password protected bash script resist/refuse “bash -x” when the password is given

I want to give my long scripts to customer. The customer must not be able to read the scripts even if he has the password. The following command locks and unlocks the script but the set +x is simply ignored. The code: read -p 'Script: ' S && C=$S.crypt H='eval "$((dd if=$0 bs=1 skip=//|gpg... (7 Replies)
Discussion started by: frad
7 Replies

5. UNIX for Dummies Questions & Answers

Im new to bash scriping and i found this expression on a bash script what does this mean.

# check host value regex='^(||1|2|25)(\.(||1|2|25)){3}$' if ')" != "" ]; then if ]; then echo host $host not found exit 4 fi elif ]; then echo $host is an invalid host address exit 5 fi espeacailly the top regex part? ---------- Post updated at 06:58 PM ---------- Previous update was... (1 Reply)
Discussion started by: kevin298
1 Replies

6. Shell Programming and Scripting

Run bash script within a bash script

Hi everybody, Lets say, I have two bash scripts named down.sh and up.sh located in two different folders named ~/home/a/ and ~/home/b/ Now I want to write another bash script, located in ~/home/ which runs these other two scripts, so that I only have to execute this one comprehensive script... (1 Reply)
Discussion started by: NBurkhard
1 Replies

7. Shell Programming and Scripting

Bash Script: modify bash

Hey guys, i'm having trouble complete one of my bash scripts I'm hoping to --- 1. Modify bash so that then the user types "ls" the command that is executed is "ls -al" 2. Modify the point of entry in bash when the user accesses it, moving the initial location to /var I've somewhat done #2,... (9 Replies)
Discussion started by: LibRid
9 Replies

8. Shell Programming and Scripting

how to make your bash script run on a machine with csh and bash

hi, i have a script that runs on bash and would like to run it on a machine that has csh and bash. the default setting on that machine is csh. i dont want to change my code to run it with a csh shell. is there any way i can run the script (written in bash) on this machine? in other words is there... (3 Replies)
Discussion started by: npatwardhan
3 Replies

9. Shell Programming and Scripting

passing variable from bash to perl from bash script

Hi All, I need to pass a variable to perl script from bash script, where in perl i am using if condition. Here is the cmd what i am using in perl FROM_DATE="06/05/2008" TO_DATE="07/05/2008" "perl -ne ' print if ( $_ >="$FROM_DATE" && $_ <= "$TO_DATE" ) ' filename" filename has... (10 Replies)
Discussion started by: arsidh
10 Replies

10. Shell Programming and Scripting

Why generate "ash and bash" different output for same bash script?

Hi, For my bash script, terminal with bash is generate an OK output and program works right. already, terminal with ash have "line 48: syntax error: Bad substitution" output and program don't work. :confused: (0 Replies)
Discussion started by: s. murat
0 Replies
Login or Register to Ask a Question