I copied a shell script from a how-to cookbook, and [of course] the first line is:
#! /bin/bash
There are any number of little script files scattered through my home range with that same first line. This one won't work. I get:
line 1: TITLEBAR: command not found
Yes, I have my home directoryin $PATH, but just to be on the safe side, I also tried running this script with "./filename", and also "bash filename", all to no avail. I have erased and re-entered that first line a coupla times just to be certain there was not some hidden quirk, and I also entered it both with (and without) a space between the "!" and the "/". No luck. Oh, yea, I DO have executable privileges (chmod 755 filename)
DSwain
06-19-2005, 07:28 PM
Can we see more of the code you're talking about? This may be able to help us give you an idea of what's going on.
The pound (#) is called a comment. Bash won't read or interpret this as anything at all so that shouldn't be the problem. Also, it'd be good to have some idea what the script is trying to do if the code isn't straightforward.
endoalpha
06-19-2005, 08:36 PM
The hash-bang ( #!) at the head of a script tells your system that this file is a set of commands to be fed to the command interpreter indicated. The #! is actually a two-byte "magic number", a special marker that designates a file type, or in this case an executable shell script (see man magic for more details on this fascinating topic). Immediately following the sha-bang is a path name. This is the path to the program that interprets the commands in the script, whether it be a shell, a programming language, or a utility. This command interpreter then executes the commands in the script, starting at the top (line 1 of the script), ignoring comments.
The #!/bin/bash IS NOT A COMMENT....
bwkaz
06-19-2005, 09:01 PM
The #!/bin/bash IS NOT A COMMENT.... Yes it is, to bash.
The kernel (or the C library) != bash. ;)
The kernel (or the C library) is what uses the #! to find an interpreter for the script. bash just reads each line, and # characters start comments for bash. It completely ignores that first line.
endoalpha
06-19-2005, 09:38 PM
He never said this was a bash script
DSwain
06-19-2005, 09:49 PM
No but he attempted to issue it with the bash command, and also the comment of #!/bin/bash
As for it being a comment or not, well as far as I know it is. I've written bash scripts without this and have had no problem. It never seemed to make much difference in my scripts. It could very well be somehthing else, though. I never understood the ! part of it. I always thought it was just to indicate the type of script to a person reading the source.
chzlchp
06-19-2005, 10:14 PM
Indeed this is a bash (shell) script. My understanding of the first line is that it (a) kick starts the text file as an executable script [#!], and then (b) clarifies the arena wherein the execution will occur [/bin/bash]. As I say, I have many other script text files laying about (with this clarification...I am new at this and learning, so the following script is probably the most *****ios thing I've done so far).
#! /bin/bash
function prompt_command {
# save the current position
tput sc
# backwash is where to position the cursor
# to write the whole current working directory
# we back up 2 more for the brackets
let backwash=$(tput cols)-$(echo $(pwd) | wc -m)-2
# position the cursor at Y=0, X=calculated length
tput cup 0 ${backwash}
# set foreground color, bold
tput setaf 4 ; tput bold
# wrap the full path in brackets
echo -n "["
# set the color of the current path
tput setaf 6
# show the path
echo -n "$(pwd)"
# set the color of the closing bracket
tput setaf 4 ; tput bold
# show the closing bracket
echo -n "]"
# return cursor to the saved position
tput rc
}
...and it goes on from there. I've looked thru the text for typos, and haven't been able to find any. There are no syntactical errors, or the editor would have warned me. Odd that the execution appears to hang up on the very first line. Dunno?!
DSwain
06-19-2005, 10:27 PM
Well the function looks okay from what I can tell but I don't see anything related to a thing called TITLEBAR in the script at all. Is there anything along those lines in the script anywhere?
bburton
06-19-2005, 11:04 PM
Try it without the space between the "#!" and the "/bin/bash".
IE: #!/bin/bash, not #! /bin/bash
chzlchp
06-19-2005, 11:19 PM
Well the function looks okay from what I can tell but I don't see anything related to a thing called TITLEBAR in the script at all. Is there anything along those lines in the script anywhere?
Absolutely nothing in the entire file with that name. I looked in all the usual dark corners (man pages, google, info, apropos, etc,, etc.) for such a name. As noted up in one of my earlier posts, it appears on the command line as would any error that stops a script from running...you know, where the line number and a description of the error are spelled out. I even tried doing an "echo $TITLEBAR" to no effect, so it's not a variable. Dunno?! Maybe it's some obscure little forgotten corner that Mr. Bourne stuck in and forgot about, and it's taken all these many years to surface again.
To answer the other recent question...I have already tried running with and without a space between "#!" and "/bin/bash". In fact, while looking through some of my other scripts to see what else I might have done, I found examples of both formats, all of which worked. Somehow, the flaw has got to relate to something farther down in the script, and it's regressing back up to the first line (?) to wither away. As I say, I copied this text directly from a book, so I don't really understand it all that well, it's way beyond what I could have invented myself, so what flaws and/or traps it may introduce I don't know.
(BTW, this script comes from an O'Reilly book call "Linux Desktop Hacks" by Nicholas Petreley and Jono Bacon. pg 42/Hack #13)
psi42
06-19-2005, 11:47 PM
Can you post the entire script? The function you posted works fine, but you didn't post how your script calls the function in the first place...
By the way, the function itself works fine for me. Very nice trick.
chzlchp
06-20-2005, 12:21 AM
Can you post the entire script? The function you posted works fine, but you didn't post how your script calls the function in the first place...
By the way, the function itself works fine for me. Very nice trick.
#! /bin/bash
function prompt_command {
# save the current position
tput sc
# backwash is where to position the cursor
# to write the whole current working directory
# we back up 2 more for the brackets
let backwash=$(tput cols)-$(echo $(pwd) | wc -m)-2
# position the cursor at Y=0, X=calculated length
tput cup 0 ${backwash}
# set foreground color, bold
tput setaf 4 ; tput bold
# wrap the full path in brackets
echo -n "["
# set the color of the current path
tput setaf 6
# show the path
echo -n "$(pwd)"
# set the color of the closing bracket
tput setaf 4 ; tput bold
# show the closing bracket
echo -n "]"
# return cursor to the saved position
tput rc
}
This script is supposed to display the current directory in the upper right-hand corner of a text screen.
Notice in the lower section (starting with the line below 'case') I added some notation ('# indent x tabs') about indentation. I realized that the forum format eliminates left indentation.
Now, ya know...this doesn't seem to be quite fair! Here you're gonna get this thing to work perfectly on your 'puter, and I can't get it to budge. You owe me a screen shot!
psi42
06-20-2005, 02:58 AM
Okay, here is the problem:
On line 43,
PS1="$(TITLEBAR)\
should be
PS1="${TITLEBAR}\
$(TITLEBAR) actually attempts to execute the command TITLEBAR. I believe this is essentially equivalent to `TITLEBAR` but I could be wrong there.
${TITLEBAR}, on the other hand, refers to the variable TITLEBAR itself.
It's beyone me why bash told you the error was on line one, because I got
./fooscript: line 45: TITLEBAR: command not found
You might also want to know that the script never actually calls the prompt_command function.
chzlchp
06-20-2005, 06:10 AM
Thanks. I'll hafta wait 'til after work to look at it more closely. What I'll do is hit the books and figure out why you've made the suggestions you have.
1
chrism01
06-20-2005, 07:47 PM
I agree with psi42, it looks like it should be interpolating the value for the variable TITLEBAR ie use ${var} notation, not trying to run it as a cmd ie $(cmd) notation.
Re shell scripts:
if no #! line specified, and your current shell recognises it as a shell script (.sh extension), then it will try to run it using the current ie default shell. (Need min of read+execute perms).
This is very important when writing scripts on big systems/for other people. Never assume default shell is same as yours...
To see what a shell script is really trying to do, use cmd
set -xv
at the top (ie next line after #!).
HTH
bwkaz
06-20-2005, 10:23 PM
Notice in the lower section (starting with the line below 'case') I added some notation ('# indent x tabs') about indentation. I realized that the forum format eliminates left indentation. Not if you use [code] tags to mark your, err, code. :p
$(TITLEBAR) actually attempts to execute the command TITLEBAR. I believe this is essentially equivalent to `TITLEBAR` but I could be wrong there. Nope, that's right. Backticks are exactly equivalent to $(...), except the $(...) version is a lot easier to nest (because the end character is different from the start character). $(...) is a bash extension, though -- it's not part of the original Bourne shell.
chzlchp
06-21-2005, 05:27 AM
psi42 you are exactly correct. I had put parentheses (instead of brackets) around TITLEBAR on line #43. Why did my computer stop at line #1? I dunno. Maybe it's a fast reader(?), and already knew at the first line that there were problems further down?
Anyhoo, my script now does nothing! I put a couple 'echo "Text"' lines at the bottom, just to see if the script would get that far and echo them on the monitor-which it does. I believe that line #11 (let backwash=etc,, etc.) is not being evaluated. I've been entering some of these lines at the CL, just to watch what they do, and that line just echos as "100-13-2". The 'tput', 'cup', 'setaf', ect. commands work fine. So that (the math interpretation) is where I'm gonna go.
Anyway, I spent 10 hours yesterday putting a roof on a gazebo, so when I got home, there was not a lot of script scrunching accomplished! So I'm gonna hafta fiddle with this tonight when I get back. Bottom line, though? I'm getting some quality time at the screen, digging into 'man' pages, absorbing arcane stuff, and so forth. I'm getting this odd feeling that someday it all (or at least some of it!) will actually make sense.
Again, everyone, thanks for all the input.
bwkaz
06-21-2005, 07:35 PM
let backwash=$(tput cols)-$(echo $(pwd) | wc -m)-2 GAAH!!
;)
This is Yet Another Useless Use of Something (in this case, process substitution). I didn't see this earlier, but I will definitely comment on it now. :D
This line can be much more easily done like so:
let backwash=$(tput cols)-$(pwd | wc -m)-2 Remember that you NEVER need to "echo $(...)", under any circumstances. Just run the process. Don't capture its output and then re-echo that output.
I would let you do the echo -n "$(pwd)" stuff, but only because you're doing an echo -n, and not a normal echo. However, the output of the shell builtin "pwd" command is exactly the same as the $PWD shell variable (at least under bash), so you can replace it with this:
echo -n "$PWD" and get exactly the same output. (Without wasting a process, even.)
chzlchp
06-22-2005, 03:25 AM
Is it possible, in bash, to 'step' thru a script? i.e., call the script, but have it execute one line at a time, pausing after each increment, waiting for input (anykey)?
I had thought of inserting a 'user input' line where I wanted the execution to pause, but I can't find anything in the man pages or in any of my books about this subject. (i.e., something like, 'raw-input').
chrism01
06-22-2005, 03:38 AM
See the read cmd here: http://www.tldp.org/LDP/abs/html/internal.html#EX36
Also, as I said, if you use 'set -xv' near the top, it'll dump out everything it's doing before and after translating vars to values.
chzlchp
06-22-2005, 05:21 AM
Has anyone gotten any of this to work?
Going thru the lines one-by-one on the CL, I can get it to actually move the command line (to the designated x/y location), and I can change the colors, but as soon as I return the command line to its' default spot, everything else is wiped out. I suspect that that is what is happening when I invoke the script. It all happens, but it all happens too fast to be seen.
Once I have the desired effect (a 'pseudo' command line) displayed in the upper right, I want to freeze that. That's what I can't seem to get accomplished.
justlinux.com
Copyright Internet.com Inc. All Rights Reserved.