LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-22-2017, 08:26 AM   #1
Cobraone72
LQ Newbie
 
Registered: May 2010
Posts: 4

Rep: Reputation: 1
Post Bash - while IFS and external variable management


Hello everyone,

I'm trying to get familiar with bash and Scripting and i would to realize something that get some command (with variable) from an external file and elaborate it in a cycle in a bash.

This is what i've made (and the problem i'm not able to solve atm).

in the main bash i declare some variables like:
Dirname (a specific directory)
DateYmd
DateHMS
and then a LogDir=Logs"_"$DirName"_"$DateYmd"_"$DateHMS

then i wrote:

while IFS='' read -r line || [[ -n "$line" ]]; do
if $line > /dev/null 2>&1;then
echo "Success....... - $line"
else
echo "FAILED........ - $line"
fi
done < "$1"

I launch this with the scriptname.sh commands.txt


in the "commands.txt" there's something like
/bin/mkdir "$LogDir"
/cp /etc/hosts "$LogDir"

the problem is that this cycle is not able to let bash manage the $LogDir variable and it creates a dir named $LogDir

if i do not use variables everything works well. There's any way to let Bash manage it?

Thanks in advance

Last edited by Cobraone72; 05-22-2017 at 08:28 AM. Reason: modified whife with while :)
 
Old 05-22-2017, 09:36 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,821

Rep: Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084Reputation: 3084
Please use [code][/code] tags around code/data

You could use eval on your 'line' variable of course the danger is if the commands.txt has a nasty piece of code in it you have no way to know until after it is run and the damage is done.

Alternatively, you could source the commands.txt file, but this would run all commands and again, you would want to know the contents prior so not to run malicious code.

I would add that you do not need to set IFS in this case as by having a single variable passed to read, the entire line will be read into that variable.
Also, the use of '-n' would seem mute because if read couldn't get any data from the file, there would be nothing in 'line'. If the line is empty then 'line' will be empty but it will still
be a successful read, hence the '-n' would not be looked at.
 
1 members found this post helpful.
Old 05-22-2017, 10:02 AM   #3
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,354
Blog Entries: 13

Rep: Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411Reputation: 4411
I think we need to see some more of the script to understand how you are assigning variables here. But you definitely do not need to have quotes around that variable name when you execute the mkdir and cp commands. Also, it is typically not /cp. Either fine the real path for cp, or don't try to explicitly specify that and let the system path variable take care of this.

One thing I always recommend is just after the shebang line, to add a "set -xv" to enable verbose debugging for your script. You can comment that line out using the # character at the start of the line to option this debug on and off as you debug the script. Further, you can move it lower in the script to enable debugging only in places where you are testing and debugging certain code. "set +xv" also reverts the state of that.
Code:
/bin/mkdir $LogDir
cp /etc/hosts $LogDir
should work fine
 
Old 05-23-2017, 02:12 AM   #4
Cobraone72
LQ Newbie
 
Registered: May 2010
Posts: 4

Original Poster
Rep: Reputation: 1
Complete script

I try to explain exactly what i'm doing a complete way..

There are several systems that has an appliance installed and some paths are different (example log path is /var/log/DirSite1 /var/log/DirSite2 etc etc). Those systems are in some networks that could not access to internet so i wanted to create a script that collects all configuration files, gzip them so che customer could send me everything.

The idea is simple.. I declare some variables (sitename,time, date and the new log dir path created with Logs_Sitename_date_time format, and then i go to the paths to collect the files i need. The main script goes to read into a file nammed command.txt the "relative" paths and copy them into the new dir log i've crated and then zip everything

The problem is that in the While Ifs cycle the variables i've declared in the initial part of the script are lost

this is the example code (complete)
Note: the DirName variable gets the name of the site because there's a dir in home named siteName1 SiteName2, the result will be Name1 or Name2)


#!/bin/bash
clear
# Declare system fixed variables
DirName=$(ls /home/ | grep -i site | awk '{print substr($0,5)}')
DateYmd=$(date +%Y%m%d)
DateHMS=$(date +%H%M%S)
LogDir=Logs"_"$DirName"_"$DateYmd"_"$DateHMS
# Create start point in Getlogs.log
echo Site: $DirName - Date $DateYmd - Time $DateHMS | tee -a GetLogs.log
# Execute commands in commands.txt
while IFS='' read -r line || [[ -n "$line" ]]; do
if
$line > /dev/null 2>&1;then
echo "Success....... - $line" | tee -a GetLogs.log
else
echo "FAILED........ - $line" | tee -a GetLogs.log
fi
done < "$1"


so i create a txt file named commands.txt where into you could put those lines

/bin/mkdir "$LogDir"
/bin/cp /etc/hosts "$LogDir"
/bin/cp /etc/fstab "$LogDir"
/bin/cp /etc/init/site"$DirName"/* "$LogDir"

(i tired with or without " and the result is the same)

Pratically when a command is passed into the while cycle the system is unable to retain the variable value and create a dir named $LogDir and copies files into a new file named $LogDir

i tried to move the variables into the cycle after while but the result is the same. It is like reading from an external file let variables to be lost.

Any solution or there's no way to solve them?

Regards
 
Old 05-23-2017, 05:52 AM   #5
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,614

Rep: Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607Reputation: 5607
you can simply:
source commands.txt
to do that job
 
  


Reply

Tags
bash, ifs, variables


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
BASH: Since when did setting your IFS... L_Carver Linux - Software 3 12-05-2016 02:08 AM
Does IFS only work on variable expansion? glenjoker Linux - Newbie 7 10-15-2015 09:30 AM
[SOLVED] Why cann't I find IFS variable in my system quitus Linux - Newbie 1 01-02-2015 11:14 PM
Bash: when an empty IFS does not work like a default IFS (info) catkin Programming 13 04-19-2012 09:40 AM
setting IFS variable infamous41md Linux - Newbie 2 05-20-2003 06:12 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 12:02 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration