bash script code error on command output to varible

     #create LinuxScanFolders cfg file if not present
     if  -f "/var/log/VirusVault/scanvirus.cfg" ]]; then
        printf ""
     else
        printf "creating LinuxScanFolders
"
        cat > /var/log/VirusVault/scanvirus.cfg <<EOL
__________scanvirus configuration__________
___________________________________________
Excluded Scan Folders
etc dev proc tmp mnt media srv .snapshots
___________________________________________
Time Date Stamp
date '+%Y-%m-%d %I:%M%P'
___________________________________________
EOL
     fi

     #setup configuration lines into array
     IFS=$'
' read -d '' -r -a lines < /var/log/VirusVault/scanvirus.cfg

     printf "excluded folders: %s
" "${lines[3]}"
     printf "time date stamp : %s
" "${lines[6]}" 
        
    
     Time_Date_Stamp=$( "${lines[6]}" ) 
     # check for date command error
     #if  $? != 0 ]]; then
     #     echo "----- Time_Date_Stamp error -----"
     #     exit 1
     #fi

     printf "%s
" $Time_Date_Stamp


It checks for the config file. Creates it if needed. Then reads the file lines into an array. Assigns the time_date_stamp from a line in the file.

excluded folders: etc dev proc tmp mnt media srv .snapshots
time date stamp : date '+%Y-%m-%d %I:%M%P'
./scanvirusa: line 136: date '+%Y-%m-%d %I:%M%P': command not found


I can’t find the error. Need help.

Hi
Missing backticks…


`date '+%Y-%m-%d %I:%M%P'`

I replaced date in the CFG file. It still errors.

`date '+%Y-%m-%d %I:%M%P'`
Time_Date_Stamp=$(`("${lines[6]}")`) 
Time_Date_Stamp=$(`"${lines[6]}"`)

./scanvirusa: line 136: date '+%Y-%m-%d %I:%M%P': command not found

From the error message we can infer bash is taking the whole line as the command name, whereas we want only “date”. You could remove double quotes from the command, but from a quick test it seems it’s doing word splitting, ignoring the single quote. I wish I knew why.
If you can change the format in the .cfg file, I suggest you omit the “date” part, and prepend the date command before the quoted line. Not a definitive solution, but may work in your case.

     Time_Date_Stamp=$( "${lines[6]}" ) 
date '+%Y-%m-%d %I:%M%P' 2020-04-23 10:53pm  
Time_Date_Stamp=$(date '+%Y-%m-%d %I:%M%P') printf "%s
" $Time_Date_Stamp 
2020-04-23 10:55pm 

command output to string is adding a newline.

printf -v Time_Date_Stamp "%s" $(date '+%Y-%m-%d %I:%M%P') printf "%s
" $Time_Date_Stamp 
2020-04-2310:59pm

ARG! (sigh)

He has $( date ‘+%Y-%m-%d %I:%M%P’ ), which is a more modern (for 30 years at least) and better readable form of .....

Not sure what you mean by that, the single quote I refer to is inside the .cfg file. With the double quotes above word splitting doesn’t occur.

Hi


#!/bin/bash

        cat > scanvirus.cfg <<EOL
__________scanvirus configuration__________
___________________________________________
Excluded Scan Folders
etc dev proc tmp mnt media srv .snapshots
___________________________________________
Time Date Stamp
date '+%Y-%m-%d %I:%M%P'
___________________________________________
EOL

        cat >> scanvirus.cfg <<EOL
__________scanvirus configuration__________
___________________________________________
Excluded Scan Folders
etc dev proc tmp mnt media srv .snapshots
___________________________________________
Time Date Stamp
`date '+%Y-%m-%d %I:%M%P'`
___________________________________________
EOL

cat scanvirus.cfg

 ./scan_test

__________scanvirus configuration__________
___________________________________________
Excluded Scan Folders
etc dev proc tmp mnt media srv .snapshots
___________________________________________
Time Date Stamp
date '+%Y-%m-%d %I:%M%P'
___________________________________________
__________scanvirus configuration__________
___________________________________________
Excluded Scan Folders
etc dev proc tmp mnt media srv .snapshots
___________________________________________
Time Date Stamp
2020-04-24 09:19am
___________________________________________

The backticks are evaluated at the time of “cat <<EOL”, it means the .cfg file holds now a timestamp instead of a format. To avoid that, use “cat <<‘EOL’” (single quote EOL) but that leads to the original issue.

Because you placed a
ewline in the printf format string. $() itself removes the last newline if any.

printf -v  Time_Date_Stamp "%s" "$(date '+%Y-%m-%d %I:%M%P')"; printf  "%s
"  "$Time_Date_Stamp" 
2020-04-23 10:59pm

Notice double quotes around both $ substitutions above.

Adding semicolons where required as well.

printf by example:

printf "%s

" DATE TIME
DATE
TIME

printf “%s” DATE TIME

DATETIME (no new line)

printf "%s

" “DATE TIME”
DATE TIME

Talking about ‘readable’:

  • The ‘+%Y-%m-%d’ can be replaced by ‘+%F’
  • Given the format chosen, the var should be called Date_Time_Stamp
  • Using %H:%M will use a 24 hour format, which makes the AM/PM unneeded, and give a more natural sorting order.
  • IMHO the vars should not be in the cfg, but in the script.
    Also:
  • I’d never do this with a line number reference. Insert one line and the script won’t work anymore.

Hi
Yes, just source it and put the config down in .config directory, or /etc…

The output here is wrong. Some spaces are new lines.

printf -v Time_Date_Stamp “%s” $(date ‘+%Y-%m-%d %I:%M%P’)
printf "%s
" $Time_Date_Stamp

2020-04-2310:59pm

Time_Date_Stamp=$(date ‘+%Y-%m-%d %I:%M%P’)
printf "%s
" $Time_Date_Stamp

2020-04-23
10:55pm

#date ‘+%Y-%m-%d %I:%M%P’
2020-04-23 10:53pm

Replace the space with an underscore. IMNSHO spaces in generated filenames are horrible.

Another option is to put the
to the end of the line.

Using the above changes, here is the code. Note, this file can be changed by users to any format. A simple copy and paste into the file.

     #create LinuxScanFolders cfg file if not present
     if  -f "/var/log/VirusVault/scanvirus.cfg" ]]; then
        printf ""
     else
        printf "creating scanvirus configuration
"
        cat > /var/log/VirusVault/scanvirus.cfg <<EOL
__________scanvirus configuration__________
___________________________________________
Excluded Scan Folders
etc dev proc tmp mnt media srv .snapshots
___________________________________________
Date Time Stamp
'+%Y-%m-%d %I:%M%P'
___________________________________________
EOL
     fi

     #setup configuration lines into array
     IFS=$'
' read -d '' -r -a lines < /var/log/VirusVault/scanvirus.cfg

     printf "excluded folders: %s
" "${lines[3]}"
     printf "date time stamp : %s
" "${lines[6]}" 

     DTS_tmp="${lines[6]}"
     #Date_Time_Stamp=$(date '+%Y-%m-%d %I:%M%P')
     printf -v  Date_Time_Stamp "%s" "$(date "${lines[6]}")"
     printf  "%s
"  "$Date_Time_Stamp"


excluded folders: etc dev proc tmp mnt media srv .snapshots
date time stamp : ‘+%Y-%m-%d %I:%M%P’
date: invalid date ‘‘+%Y-%m-%d %I:%M%P’’

The proper format for readable code should be that: Date_Time_Stamp

However the user can make the stamp in any format they like. The stamp is used on some folders[ostype stamp]. The virus logs (-vl) has it’s own stamp(for sorting) first then user’s format. It’s very large script. :wink:

Yes, direct line number references will cause problems if the user alters the file. But, I need to get the code working first before I make more error checking and reformat the file. The script is still missing lots of error checking.

Sorting by date is done by the vl function. I don’t have it by hour and day. Unless someone requests it by the hour, I’m going to leave it out. By year-month-day is next on my list.

view logs
p1: -vl
p2: l or m mask by linux/mswin scans (optional)
p2: d mask by date (optional)
p3: year (optional)
p4: month (optional)

Yes, putting filenames with spaces has caused me a lot of problems. One reason I never called it a stable release, all kinds of design flaws.
I can use the TR command before displaying filenames with underscores.

echo "hello_there_good_day" | tr '_' ' '

Hi,

Not related to your issue but since you’re using printf might as well use that feature in bash

Time_Date_Stamp=$(printf '%(%Y-%m-%d %I:%M%P)T
')
echo "$Time_Date_Stamp"

Or if you really want the -v option

printf -v Time_Date_Stamp '%(%Y-%m-%d %I:%M%P)T
'

The**
** is optional .