LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
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 02-01-2016, 10:27 AM   #1
hopeless_n00b
LQ Newbie
 
Registered: Aug 2014
Posts: 21

Rep: Reputation: Disabled
Question [SOLVED] bash script: can echo command, command works if I type, but command doesn't work in script ... why?


My goal is to understand what is going on:
The following script is given the name 'marg':

------------------------------------------------
#!/bin/bash

d=$(dirname "$1")
b=$(basename "$1")

echo find "$d" -name ""$b"" -type f -print
------------------------------------------------

If I type

marg './foo/*' bar/

in an xterm, the result is

find ./foo -name "*" -type f -print

If I type the above command into an xterm it executes ok.

But if I change marg to
------------------------------------------------
#!/bin/bash

d=$(dirname "$1")
b=$(basename "$1")

find "$d" -name ""$b"" -type f -print
------------------------------------------------

then If I type

marg './foo/*' bar/

in an xterm, the result is that the find command does not execute.

WHY?

P.S. For those wondering "what am I trying to do?" the answer is: I am trying to understand what is going on with the above.

P.P.S. I have spent time looking online and reading man pages, but I obviously do not understand the fundamental principles... could some kind soul walk me through exactly what is going on and why removing the echo from the script does not result in the find command working?

Last edited by hopeless_n00b; 02-01-2016 at 11:23 AM. Reason: SOLVED
 
Old 02-01-2016, 11:05 AM   #2
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Remove the second set of quotes around $b in your find, they're messing things up. I think your intention is to add quotes into the command, but of course you can't nest quotes like that. "" is just an empty string, so you have [empty string]*[empty string]. Since the asterisk isn't quoted, it's being treated as a globbing pattern, rather than a literal asterisk, which is screwing up the find.

Also, add "set -x" at the top of your script after the shebang for testing things like this.

Code:
#!/bin/bash
set -x

d=$(dirname "$1")
b=$(basename "$1")

find "$d" -name "$b" -type f -print

Last edited by suicidaleggroll; 02-01-2016 at 11:06 AM.
 
1 members found this post helpful.
Old 02-01-2016, 11:22 AM   #3
hopeless_n00b
LQ Newbie
 
Registered: Aug 2014
Posts: 21

Original Poster
Rep: Reputation: Disabled
Smile

Thanks... I think you got me over my sticking point.
 
Old 02-01-2016, 11:25 AM   #4
Habitual
LQ Veteran
 
Registered: Jan 2011
Location: Abingdon, VA
Distribution: Catalina
Posts: 9,374
Blog Entries: 37

Rep: Reputation: Disabled
Code:
bash -x /path/to/script.sh
works too I believe.
 
Old 02-01-2016, 10:29 PM   #5
josephj
Member
 
Registered: Nov 2007
Location: Northeastern USA
Distribution: kubuntu
Posts: 214

Rep: Reputation: 112Reputation: 112
A few additional thoughts

If you needed to use echo (e.g. if there were other strings to add ... )

Code:
echo "I found [" $(find "$d" -name "$b" -type f -print) "]"
(Note that the quotes are fixed as per @suicidaleggroll.)

Also, note that your example

Code:
marg './foo/*' bar/
calls marg with two arguments because there is white space between ' and bar/.

Since your script only has one argument, the second one is ignored (after it is expanded). That's why you don't see bar anywhere in your example output.

In line with @habitual's suggestion,

I have a file called bash_trace in my ~/bin directory which contains:

Code:
shopt -s -o xtrace  # debug
shopt -s -o verbose  # debug
If I have a script I will use more than once or that needs work, I often include the line

Code:
##source "~/bin/bash_trace" ## debug
in it somewhere near the top. Then, whenever staring at the code isn't enough, I just uncomment that line and run it again to get a full trace. This lets me set and unset both options just by uncommenting or commenting out one line.

The source statement or just plain . tells bash to read that file as if it was part of the script - just like an include statement in other languages.

The shopt sets shell options. (There are a lot of them.) -s stands for set or turn on and -o says which option to affect.

verbose is the same as the -v command line option which prints shell command lines as they are read.

xtrace is the same as the -x command line option which prints the command line after it has been expanded.

This lets you see the command the way you wrote it and then shows you what "marvelous" things bash did to expand it before actually trying to execute it.
 
Old 02-03-2016, 04:07 PM   #6
gyles19
LQ Newbie
 
Registered: Jan 2016
Distribution: Ubuntu & Debian
Posts: 5

Rep: Reputation: Disabled
Install the bashdb package for your distro, and use it to single-step through scripts, inspect variables, etc. It's not perfect but it's usually quite informative, especially if you put -xv on your hashbang inside the script being debugged.
 
Old 02-05-2016, 03:58 PM   #7
Norseman01
Member
 
Registered: Nov 2012
Posts: 85

Rep: Reputation: Disabled
some additional thoughts

[QUOTE=hopeless_n00b;5491087]My goal is to understand what is going on:
The following script is given the name 'marg':

...skip

#!/bin/bash

d=$(dirname "$1")
b=$(basename "$1")

find "$d" -name ""$b"" -type f -print
------------------------------------------------
...skip
then If I type
marg './foo/*' bar/

...skip
===========================

In your initial question you use:

marg './foo/*' bar/

Legacy bash states that something enclosed in apostrophes is to be taken litterly
and those between quotes is to be expanded.
for those who had bad English teachers:

..apostrophe(s) is/are also referred to as single quote(s)
..quote(s) is/are also referred to as double quote(s).

since you are using bash to differentiate the path and the filename anyway, you probably should simply make the marge call:
..marge "./foo/*bar" #assumes filename ends in anythingbar
... or
..marge "./foo/*.bar" #assumes filename ends in .bar
... or
..marge "./foo/*bar*" #assumes seeking anythingbaranything

the echo should be removed because find could return a few thousand matches and
-print does the echo part anyway.

I add the echo to the front of search loop commands to check if the loop is going to do what I think it will rather than what it actually got told. Once bash and I agree on the desired results I remove the echo from the front of the command line (the find line in your case) and send it off to work.


Norseman01
 
1 members found this post helpful.
Old 02-26-2016, 01:01 PM   #8
cesarbergara
Member
 
Registered: Feb 2012
Location: Buenos Aires, Argentina
Distribution: Debian, Suse, Mandrake,
Posts: 92

Rep: Reputation: Disabled
Hi. "" Are special characters. All you put between them are literal. You can put "'" and "" or "$" when you need show those specials characters (if you have a variable VARIABLE, you can show variable contents with:
echo $VARIABLE
or show variable name with:
echo "$VARIABLE"

Without "", \ convert next character from special in normal, for example, in empty space:
HI\ MY\ NAME
Try with:

VAR1="HI MY NAME" ; echo $VAR1; unset VAR1; echo $VAR1
VAR1=HI\ MY\ NAME ; echo $VAR1; unset VAR1; echo $VAR1
VAR1=HI MY NAME ; echo $VAR1; unset VAR1; echo $VAR1
VAR1=HI"" MY"" NAME ; echo $VAR1; unset VAR1; echo $VAR1
VAR1=HI"\ "MY "\ "NAME ; echo $VAR1; unset VAR1; echo $VAR1

and you can see differences.

You can find lot of combinations with special characters (" , ' , \ , $ , % , & ; etc) in:
man bash


Have a nice day.
 
Old 02-26-2016, 01:09 PM   #9
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Quote:
Originally Posted by cesarbergara View Post
Hi. "" Are special characters. All you put between them are literal. You can put "'" and "" or "$" when you need show those specials characters (if you have a variable VARIABLE, you can show variable contents with:
echo $VARIABLE
or show variable name with:
echo "$VARIABLE"
Incorrect

double quotes do not prevent variable substitution.
echo $VARIABLE
and
echo "$VARIABLE"
will provide the exact same output.

single quotes are what prevents variable substitution.
 
2 members found this post helpful.
Old 02-26-2016, 01:11 PM   #10
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192
Please use Thread tools to actually mark the question as SOLVED
 
Old 07-12-2018, 05:57 AM   #11
tarvinder91
LQ Newbie
 
Registered: Jul 2018
Posts: 1

Rep: Reputation: Disabled
solved

Thanks a lot. I have always used echo to see what my command will actually look like. However set -x should be used to see what actual command is running.
 
  


Reply



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 - command works directly in command line but not in script raoulcousins Linux - Newbie 6 08-21-2013 07:43 PM
Command works when pasted at command line but not as bash script neild Programming 7 09-23-2012 07:30 AM
[SOLVED] Command line works, won't work from inside bash script w6lsn Programming 4 02-17-2011 05:45 AM
busybox command works, same command within script says permission denied jeroenv Linux - Newbie 2 01-17-2009 02:58 AM
Bash Script, no new line for echo command jorisb Linux - General 5 11-05-2005 12:08 AM

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

All times are GMT -5. The time now is 04:10 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