LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-16-2010, 08:31 AM   #1
chuckj
LQ Newbie
 
Registered: Mar 2010
Posts: 8

Rep: Reputation: 0
bash script: executing string command


I am trying to parse the output of fdisk so I can approximately duplicate a partition table on a drive with different parameters (there's probably a better way). In an attempt to be a "true" linux geek, I'm trying to do it with a shell script.

Yesterday I figured out how to make something work, but it doesn't make sense to me why my first attempt failed. I'm hoping someone can explain the obscure rule/behavior that caused me grief.

To parse the partition lines, I constructed this string:

"sudo fdisk -c -l /dev/sda | egrep ^/dev/sda1"

and assigned it to $scmd. I'm not showing the code to generate it, but if I "echo"ed it, the string, without quotes, is what you would see.

When I executed the string:
parm=$( $scmd );

I would get the entire output of the call to fdisk. Oh, and it would complain about the -E for grep, so I changed it to egrep. I suspect this complaint (about the -E argument) is related to the observed behavior.

What seems to be happening is that the fdisk command is being processed as if it were all on one line, so of course grep matched it and returned everything.

If I pass the following

parm=$( ${fcmd} | grep -E ^$pname );
where
fcmd="sudo fdisk -c -l /dev/sda"
and
pname=/dev/sda1

I get the result I want (a single line from fdisk output).

I've fixed my problem, but I want to understand why executing the string gave different results. I have to say that these BASH rules about quotes interpretation and parameter expansion give me a headache.

Thanks in advance if anyone wants to tackle this...

Chuck Jungmann
 
Old 06-16-2010, 08:50 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,974

Rep: Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179
There are potentially a lot of other issues with this code snippet which I will leave you to investigate further, but try the following and
see how you get on:
Code:
parm=$(eval $scmd)
 
Old 06-16-2010, 09:23 AM   #3
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Perhaps it's better if you try to learn and use sfdisk. It's a lot more scriptable although more dangerous.
 
Old 06-16-2010, 09:29 AM   #4
chuckj
LQ Newbie
 
Registered: Mar 2010
Posts: 8

Original Poster
Rep: Reputation: 0
After posting, I tried:
fd=$( sudo fdisk -c -l /dev/sda )

If I use it like
line=$( echo "$fd" | grep -E /dev/sda2 )

it works pretty well, the quotes around $fd keep the line feeds undisturbed.

My further problem, that I didn't describe in the original post but is related to string expansion, is the asterisk "*" that indicates it's bootable is expanded to the contents of my home directory. How do I defeat the expansion?

Thanks for the two suggestions, I may try eval, but I've seen warnings against it, so I avoid it.

I will try sfdisk, it looks like it's much closer to the utility I need.

Thanks for your help

Chuck
 
Old 06-16-2010, 12:40 PM   #5
chuckj
LQ Newbie
 
Registered: Mar 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Reporting my solution:
(though I'd still like to understand WHY these things "failed")

I used tr to convert the * to % to avoid the expansion:

dline=$( echo "$fd" | grep -E "^$pname" | tr '*' '%' )

Chuck
 
Old 06-16-2010, 06:20 PM   #6
Andrew Benton
Senior Member
 
Registered: Aug 2003
Location: Birkenhead/Britain
Distribution: Linux From Scratch
Posts: 2,073

Rep: Reputation: 64
Bash can do string substitution itself like this
Code:
dline=$( echo "${fd//*/%}" | grep -E "^$pname")
 
Old 06-16-2010, 09:48 PM   #7
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
With regards to Mr. Andrew Benton's solution, if it still doesn't work, maybe you should first verify that you are having the the proper contents in $fd and $pname.
 
Old 06-17-2010, 04:47 AM   #8
chuckj
LQ Newbie
 
Registered: Mar 2010
Posts: 8

Original Poster
Rep: Reputation: 0
I had some trouble with Mr. Benton's solution until I realized that the asterisk had to be escaped:
"${fd//\*/%}"

I appreciate his useful coding advice, and I am using his suggestion. Considering the undefined results of expanding asterisks, it's surely best to remove them as soon as possible, rather than using "tr" at the end of the command line.

I'm not sure about the protocol here with respect to assigning a "SOLVED" status to the thread. My original post was about an unexpected script behavior that I had already worked around. In effect, it was solved before I posted. Having already found a workaround, I am just trying to understand the arcane details of BASH scripting. There are two things I'm curious about:

1. Why did running my original command from a string result in newlines being converted to spaces when running the same command as a command substitution preserve the newlines?

2. Is there a method of using a string's contents without expanding the asterisk?

I suppose forums are generally about solutions. I came, however, seeking "wisdom."

Thanks for your responses.

Chuck
 
Old 06-17-2010, 07:22 AM   #9
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Quote:
Originally Posted by chuckj View Post
1. Why did running my original command from a string result in newlines being converted to spaces when running the same command as a command substitution preserve the newlines?
By string do you mean a variable? A variable expands depends on the contents of IFS. Basic syntax rules like separation of arguments by tokens and separation of commands by newlines does not really apply when it comes to variables.

Code:
IFS=:
VAR="a:b:c"
a:b:c() { echo a:b:c; }

echo "1: "$VAR
echo "2: ""$VAR"
echo -n "3: "
$VAR
echo -n "4: "
"$VAR"

IFS=$' \t\n'  # normal
echo "5: "$VAR
echo -n "6: "
$VAR
echo -n "7: "
"$VAR"
Quote:
2. Is there a method of using a string's contents without expanding the asterisk?
Many but basically you have to quote it inside double quotes.
Code:
VAR='*'
echo $VAR
echo "$VAR"
The two echos will have different effects. Also be careful with [ and ?. They also expand.

You can also checkout the builtin command shopt and the option noglob. Do 'man bash' for them.
 
  


Reply


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 Script - Passing command string between variables Devcon Programming 13 01-10-2011 10:13 AM
escape string in bash script so it can be used in command line BuckRogers01 Linux - Software 15 08-12-2010 09:38 AM
Bash script run via cron not executing MYSQL command mackstar Linux - Server 4 04-23-2009 05:01 AM
Executing a string in bash Agentrooker Programming 5 08-11-2008 03:04 PM
Bash script - passing command as string lenzj Programming 3 08-24-2006 11:36 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:51 PM.

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