ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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...
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:
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.
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.
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."
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.