Find the answer to your Linux question:
Results 1 to 7 of 7
I just started writing some simple stuff in my spare time, and I am now trying to write a script that will make a new gedit file, it asks me ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jan 2013
    Posts
    1

    noob scripter here, whats wrong with this script?


    I just started writing some simple stuff in my spare time, and I am now trying to write a script that will make a new gedit file, it asks me what I would like to name it and then inserts the #!/bin/bash on the first line so it is ready to go.

    Code:
    #! /bin/bash
    # script I wrote to make a new blank script file
    
    # variables
    
    newscript_name=" "
    
    echo "I see you have started to write a new script, good luck."
    echo "What would you like to call this new script:"
    read ${newscript_name}
    
    echo "#! /bin/bash" >> ${newscript_name}.sh
    This may seem silly and simple, but hey I am just starting out

  2. #2
    Linux Newbie
    Join Date
    Nov 2012
    Posts
    220
    hi,

    Code:
    #newscript_name=" " #useless, at least should be empty: ""
    
    echo "I see you have started to write a new script, good luck." >&2 # these comments should not be sent to stdout, but to stderr
    echo "What would you like to call this new script:" >&2 # the only thing that should be sent to stdout are data, `read -p', `select', aso, comments are sent to stderr.
    read newscript_name
    
    echo "#! /bin/bash" > ${newscript_name}.sh # make sure this line make is the first one: only one > to overwrite possible existing file.
    Last edited by watael; 01-11-2013 at 01:06 AM. Reason: mistyped stdin; should be stdout

  3. #3
    Just Joined!
    Join Date
    Dec 2009
    Location
    California
    Posts
    98
    A few things to keep in mind.

    First, before you can run the script, you have to make it executable:
    $ chmod a+rx foo
    (assuming the name of the script is foo)

    Second, I see you are using gedit. That is good. If you use notepad or any other windows program to build the script, it will add <CR><LF> at the end of every line and it won't run. You can strip those pesky extra characters like this:
    $ dos2unix foo

    Third, you don't need to pre-declare variables in shell programming so just remove the line:
    newscript_name=" "

    Fourth, you don't need to enclose your variables as you have with ${newscript_name}. Actually, its incorrect to do it on a read so change your read to:
    read newscript_name

    I'm sure some folks will be unhappy about this next statement, but I believe you should never use the ${variableName} unless it is necessary and the only time it is necessary is to disambiguate two variables from the shell. Take the following snippet for example:
    HTML Code:
    X=2
    # here I want to output the number stored in the variable X followed immediately by the letter "l" (ell)
    echo $Xl
    # if you run this, you will see that it outputs nothing because the shell thinks the variable you are trying to output is Xl not X followed by l.
    # so the right way to do this is
    echo ${X}l
    Other than that one instance, I'm not a fan of using the ${} stuff.
    Last edited by abarclay; 01-10-2013 at 01:35 AM. Reason: add formatting

  4. #4
    Just Joined!
    Join Date
    Dec 2009
    Location
    California
    Posts
    98
    Watael,
    No offence intended, but I disagree with your comment about writing prompts and output to stderr. That is simply incorrect. The prompts should be written to stdout which is the default place for echo. The only thing you should write to stderr is error messages. There are a lot of reasons for this, but here is one. Often I want to run a program and write only the error messages to a file like this:
    ./program 2>/tmp/errors

    if the person who wrote the program wrote some of the prompts and things to stderr, then my error log would be polluted (not to mention the fact that I might be sitting in front of a console window while the program is waiting for user input because the prompt was written to my error file).

    If you still aren't convinced, here is one more thought. Have you ever had a program fail and you want to debug it to find out what is REALLY going wrong with it? If that happens, you will probably run it with truss or strace which traces all the system calls and arguments. strace and truss write their output to stderr, so I would use something like this:
    strace ./testenv.sh 2>/tmp/trace.out

  5. #5
    Linux Newbie
    Join Date
    Nov 2012
    Posts
    220
    Debugging, and error redirection are not the "normal" usage of scripts.
    I'd never use strace to debug a script; I'd simply use set -x, and keep strace for compiled programs.

    As I said, read -p, and select, each PS{1..4} are sent to stderr. That's a fact. The normal way the shell works.

    My interpretation of this behaviour is that "prompts" have to be separated from data, because data is really what I want to get (in normal usage of a script).

  6. #6
    Just Joined!
    Join Date
    Dec 2009
    Location
    California
    Posts
    98
    I understand your motivation for suggesting that prompts be written to stderr instead of stdout (separation of prompts from data) [BTW, I think you mis-typed an item in your post. You wrote stdin, but I think you meant stdout].

    My argument was, " The three basic file descriptors handed to every UNIX program (stdin, stdout and stderr) are extremely well-defined. Input comes from stdin, Output goes to stdout and errors go to stderr. If you violate these tenets, then basic Unix piping and redirection breaks down."

    But, I've run a bunch of programs in my Linux system and I find that about 30% of them do what you suggest, 55% of them write prompts to stdout as I suggest, and a few of them write prompts directly to /dev/tty
    units: stdout
    gdb: stdout
    nslookup: stderr
    passwd: stderr
    mailx: stdout
    mutt: stdout
    vi: stdout
    rm {when invoked with -i}: stderr
    mail: stdout
    yppasswd: tty
    sudo: tty
    chsh: stderr
    python: tty
    gpg: stdout
    ssh-keygen: stderr

    The wikipedia entry on standard_streams states, "Standard error is another output stream typically used by programs to output error messages or diagnostics.". The prompt for user input is neither an error message nor diagnostic.

    I guess I can always argue that using stderr is less efficient as it is unbuffered

    I do concede that some folks do tend to agree with you. I guess it depends if the script author "expects" the output of his script to be redirected. Clearly there is no consensus.
    Last edited by abarclay; 01-11-2013 at 01:12 AM. Reason: add formatting

  7. #7
    Linux Newbie
    Join Date
    Nov 2012
    Posts
    220
    BTW, I think you mis-typed an item in your post. You wrote stdin, but I think you meant stdout
    yes, that's correct now. thank you.

    I guess it depends if the script author "expects" the output of his script to be redirected. Clearly there is no consensus.
    I do agree.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •