LinuxQuestions.org
Visit Jeremy's Blog.
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-21-2007, 01:10 AM   #1
kambrish
LQ Newbie
 
Registered: Jun 2007
Location: India
Posts: 12

Rep: Reputation: 0
syntax error near unexpected token in bash using perl


Hi,
I am getting this problem while running the command from shell. If I run the command directly on command prompt, its running fine.
Here, i used the back slash also to skip the special purpose of single quote, but getting the below problem.

Command is:

sh -c '(perl -pi -e \'print "TextContents" if $.==13\' "/usr/local/etc/stunnel/stunnel.conf")'

bash: syntax error near unexpected token `"/usr/local/etc/stunnel/stunnel1.conf")''

If someone can help me, it would be great!
This command is for entering a line TextContents to a file stunnel.conf file at line number 13.
Regards Ambrish
 
Old 06-21-2007, 02:58 AM   #2
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.6, Centos 5.10
Posts: 16,324

Rep: Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041
It looks like you've got a real newline break between the 2 lines there, which bash will interpret as separate cmds.
Either write it on 1 line or use '\' at the end of the 1st line, which bash will recognise as a line continuation.
It's important to know that nothing except the newline char must appear after the '\' .
Ps please post your distro in your profile.
 
Old 06-21-2007, 03:11 AM   #3
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,314

Rep: Reputation: 175Reputation: 175
messy, why don't you just make it a proper little script?

 
Old 06-21-2007, 03:12 AM   #4
kambrish
LQ Newbie
 
Registered: Jun 2007
Location: India
Posts: 12

Original Poster
Rep: Reputation: 0
Hi Chris,
The command I gave is on one line only. Once again I give, its

sh -c '(perl -pi -e \'print "TextContents" if $.==13 \' "/usr/local/etc/stunnel/stunnel.conf")'

and the error which I am getting is :

bash: syntax error near unexpected token `"/usr/local/etc/stunnel/stunnel1.conf")''

So, i suppose its the filename at the end with path which is not properly in quotes. But i am not getting exactly how to change this.

Also, i updated my profile but i am not sure what exactly is meaning of distro!
Regards Ambrish
 
Old 06-21-2007, 03:16 AM   #5
kambrish
LQ Newbie
 
Registered: Jun 2007
Location: India
Posts: 12

Original Poster
Rep: Reputation: 0
Billy,
Its part of one particular module wherein much more scripts are running, so i cannot make a separate script.
Its just one command which I am passing to another function. Thats why I need to do it in this way.
Regards Ambrish
 
Old 06-21-2007, 08:15 AM   #6
kambrish
LQ Newbie
 
Registered: Jun 2007
Location: India
Posts: 12

Original Poster
Rep: Reputation: 0
can someone update. the error is just coming, i suppose, while giving the file name in double quotes. But i am not getting, how to remove this!!
 
Old 06-21-2007, 08:34 AM   #7
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 231Reputation: 231Reputation: 231
Why are you using perl, & its complexity, for something that is almost trivial w/ sed?

Code:
# set insert line #
L=13
# set insert text
I="TextContents"
# set insert file
F="/usr/local/etc/stunnel/stunnel.conf"

sed -i "${L}i${I}" ${F}
BTW, I suspect the cause of your problem is shell quoting rules. Since I do not understand what difference you by "from shell" compared to "directly on command prompt". To me, both mean the same thing. Did you mean "from shell" to mean "inside a script"?

2nd, why are you using sh -c, rather than bash -c, your script is, after all, a bash script? In fact why are you using either? -- Can't you just put the perl command directly into the script?

Next, why the parentheses? I don't think they are normal w/ [ba]sh -c.

Finally, once again, why even use perl for this. To my way of thinking, it's swatting flies w/ a sledge hammer.
 
Old 06-21-2007, 08:57 AM   #8
kambrish
LQ Newbie
 
Registered: Jun 2007
Location: India
Posts: 12

Original Poster
Rep: Reputation: 0
Rick,
Your queries are quite correct but its a project which is already running and its already developed by someone else. We are in maintainence phase wherein need to do these updates.
Per ur queries:
Did you mean "from shell" to mean "inside a script"?
==> Yes!!

2nd, why are you using sh -c, rather than bash -c, your script is, after all, a bash script? In fact why are you using either? -- Can't you just put the perl command directly into the script?
==> Project is already developed. We need to do this small change.

Next, why the parentheses? I don't think they are normal w/ [ba]sh -c.
==> I can give my command only in parentheses as the command is passed on to some other function which is running this command.

Finally, once again, why even use perl for this. To my way of thinking, it's swatting flies w/ a sledge hammer.
==> Perl is already used in this project, so i have to use it!!
Regards Ambrish
 
Old 06-21-2007, 09:12 AM   #9
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,314

Rep: Reputation: 175Reputation: 175
I wouldn't call that a complex perl script.
also sed -i is not portable.
 
Old 06-21-2007, 09:32 AM   #10
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 231Reputation: 231Reputation: 231
Let me clarify: I wasn't saying that that snippet of perl was complex, but rather that perl itself is a complex language.

As for sed -i not being portable, that can be worked around w/ temp files -- which might be a safer way of doing things anyway.


So you/we are stuck w/ what is there.

General trouble shooting Q's:
Is this breakage a recent occurrence?
If so, can you think of anything else that changed around the same time that might be the cause?

Based on your clarification (for which, thanks), you're going to have to trouble shoot in place or in a dummy test script. It might help if you would outline the scripts/programs involved & who is passing what to whom. I think you are going to have trace what has become of your values vis-a-vis quoting rules at each step of the way. I suspect you're going to be reading the bash, & maybe other, man pages more than once.

It would also be helpful to know what you are allowed to change & what is off-limits.
 
Old 06-21-2007, 11:28 AM   #11
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
That's funny. When I copy and paste your original problem line

Code:
sh -c '(perl -pi -e \'print "TextContents" if $.==13\' "/usr/local/etc/stunnel/stunnel.conf")'
into an xterm window, it neither is free of syntax errors (as it was for you on the command line) nor gives the error message

Code:
bash: syntax error near unexpected token `"/usr/local/etc/stunnel/stunnel1.conf")''
Instead, it gives the error message

Code:
-bash: syntax error near unexpected token `)'
I'm curious as to whether you copied and pasted accurately at all points. Be that as it may, let's work with what we have.

I did the following at the command prompt. Note which commands responded with Thursday when I asked for yesterday. (All of them either do that or fail completely, except the first one, which doesn't invoke sh at all.)

Code:
wally:~/thursday$ date
Thu Jun 21 07:57:31 PDT 2007
wally:~/thursday$ date -d yesterday
Wed Jun 20 07:57:39 PDT 2007
wally:~/thursday$ sh -c date
Thu Jun 21 07:57:50 PDT 2007
wally:~/thursday$ sh -c date -d yesterday
Thu Jun 21 07:57:55 PDT 2007
wally:~/thursday$ sh -c 'date'
Thu Jun 21 07:58:03 PDT 2007
wally:~/thursday$ sh -c 'date -d yesterday'
Thu Jun 21 07:58:07 PDT 2007
wally:~/thursday$ sh -c '(date)'
Thu Jun 21 07:58:12 PDT 2007
wally:~/thursday$ sh -c '(date -d yesterday)'
-d: -c: line 2: syntax error: unexpected end of file
wally:~/thursday$ sh -c "date"
Thu Jun 21 07:58:22 PDT 2007
wally:~/thursday$ sh -c "date -d yesterday"
Thu Jun 21 07:58:27 PDT 2007
wally:~/thursday$ sh -c "(date)"
Thu Jun 21 07:58:31 PDT 2007
wally:~/thursday$ sh -c "(date -d yesterday)"
-d: -c: line 2: syntax error: unexpected end of file
wally:~/thursday$
Since it's documented that bash works one way when invoked as sh and another way when invoked as bash, let's invoke it as bash:

Code:
wally:~/thursday$ date
Thu Jun 21 08:05:04 PDT 2007
wally:~/thursday$ date -d yesterday
Wed Jun 20 08:05:09 PDT 2007
wally:~/thursday$ bash -c date
Thu Jun 21 08:05:14 PDT 2007
wally:~/thursday$ bash -c date -d yesterday
Thu Jun 21 08:05:20 PDT 2007
wally:~/thursday$ bash -c 'date'
Thu Jun 21 08:05:27 PDT 2007
wally:~/thursday$ bash -c 'date -d yesterday'
Wed Jun 20 08:05:32 PDT 2007
wally:~/thursday$ bash -c '(date)'
Thu Jun 21 08:05:36 PDT 2007
wally:~/thursday$ bash -c '(date -d yesterday)'
Wed Jun 20 08:05:41 PDT 2007
wally:~/thursday$ bash -c "date"
Thu Jun 21 08:05:46 PDT 2007
wally:~/thursday$ bash -c "date -d yesterday"
Wed Jun 20 08:05:51 PDT 2007
wally:~/thursday$ bash -c "(date)"
Thu Jun 21 08:05:57 PDT 2007
wally:~/thursday$ bash -c "(date -d yesterday)"
Wed Jun 20 08:06:01 PDT 2007
wally:~/thursday$
In summary, every invocation of bash that puts single or double quotes around the parameter to the -c option works, whether or not parentheses are used.

Bingo. Your first change is from invoking sh to invoking bash.

But wait. There's more.

You should be aware of the way bash works with single and double quotes. The normal escape mechanism with backslash ("\") doesn't work as you'd think inside single quotes. Try these at the command line:

Code:
echo '\''
echo '\"'
(If you find yourself stuck in midcommand on the first of these, enter a Ctrl-D on a line by itself, and you'll get out again.)

No, you want double quotes around the whole thing (that is, a double quote just after the "-c " and a double quote at the end of the whole command. If you do this, you'll want to escape (precede with backslash) the dollar sign ("$") and every inner double quote, but no inner single quote.

So your command will look like this:

Code:
bash -c "(perl -pi -e 'print \"TextContents\" if \$.==13' \"/usr/local/etc/stunnel/stunnel.conf\")"
I tried this (but with a shorter file name), and it worked.

But you can also lose the parentheses. The effect of single parentheses is to fire up a new shell, but you're doing that already. That leaves you with:

Code:
bash -c "perl -pi -e 'print \"TextContents\" if \$.==13' \"/usr/local/etc/stunnel/stunnel.conf\""
I tested that one also (with a shorter file name). You also don't need the quotes around the filename. This leaves you with:

Code:
bash -c "perl -pi -e 'print \"TextContents\" if \$.==13' /usr/local/etc/stunnel/stunnel.conf"
I tested that one also (with a shorter file name).

Try these changes both on the command line and in your script.

Hope this helps.
 
Old 06-21-2007, 11:36 AM   #12
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
Oh. And.

"Distro" is slang for "distribution". See the other posts in this thread for examples.

I re-read what I wrote, and have to ask: Why is it again that you need parentheses in the -c option? Can you be more specific?
 
Old 06-21-2007, 03:56 PM   #13
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 231Reputation: 231Reputation: 231
Great analysis, wish I understood bash quoting well enough to have written that.

kambrish, I know you may be asleep, but please post back soonest.
 
Old 06-22-2007, 12:01 AM   #14
kambrish
LQ Newbie
 
Registered: Jun 2007
Location: India
Posts: 12

Original Poster
Rep: Reputation: 0
wjevans,
Thanx alot for the wonderful explanation. I tried it (from command line) and it worked!! Indeed, i am not an expert in shell, but your explanation has helped alot.
But let me give u little explanation of how its going in code and why I am using sh -c instead bash:

My code looks as below:

$exec_info = ginstall_common::execute_backquoted_command(
"perl -pi -e \'print \"TextContents\" if \$\.==13\' \"\/usr\/local\/etc\/stunnel\/stunnel1.conf\"",
);

The command goes like this in the function execute_backquoted_command

Now, if you see part of execute_backquoted_command where the above command is taken, it looks like below:

verbose::verbose(3, "sh -c '(@{commands_list})' " .
"> $ginstall_common::stdout_capt_fname 2> $ginstall_common::stderr_capt_fname");


So, here sh -c is coming which I cannot change as it impacts other modules too. For me only option is to pass the command to the function.

Ok, if this sh -c solution doesnt work, is there any other way or any other single command by which I can insert text contents at some particular line?
Kind Regards Ambrish
 
Old 06-22-2007, 07:34 AM   #15
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
Quote:
Now, if you see part of execute_backquoted_command where the above command is taken, it looks like below:

verbose::verbose(3, "sh -c '(@{commands_list})' " .
"> $ginstall_common::stdout_capt_fname 2> $ginstall_common::stderr_capt_fname");


So, here sh -c is coming which I cannot change as it impacts other modules too. For me only option is to pass the command to the function.
I'm not sure I can help very much here. I have two suggestions, both of them possibly quite lame.

The first is this: I cannot imagine that changing the function to use bash instead of sh would harm other users, unless the software is also being used where bash is not available. Is there any way you can push through a change to the function? (I realize that what I'm asking is often foolish in a larger software environment.)

The second is this: If you can't or shouldn't change the function, can you add a new one which uses bash instead of sh?

As I said, lame, but ... (sigh)

EDIT:

I just thought of a third way.

Since it appears that passing parameters works with bash but not with sh (see my example above with Wednesday/Thursday), and you're restricted to using Perl, is there any way you can write a special-purpose Perl script which performs the file modification and uses environment variables rather than command-line parameters?

Last edited by wjevans_7d1@yahoo.co; 06-22-2007 at 07:40 AM.
 
  


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
syntax error near unexpected token deskjockey39 Linux - General 2 01-16-2007 09:47 AM
syntax error for unexpected token `(' Steve Spurr Linux - Newbie 6 09-22-2006 09:19 AM
syntax error near unexpected token `else' josedias Programming 3 09-11-2006 08:09 PM
Trouble with Bash -- syntax error near unexpected token `fi' anamericanjoe Programming 5 05-19-2006 03:59 PM
syntax error near unexpected token ` mattyspatty Programming 8 05-07-2006 06:19 PM


All times are GMT -5. The time now is 10:07 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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration