LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
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 01-26-2018, 01:04 PM   #1
Tobias Kraemer
LQ Newbie
 
Registered: Jan 2018
Posts: 2

Rep: Reputation: Disabled
getopt within tcsh question


Hello all,

I have a question regarding the "getopt" command within a tcsh script (but this is a more general question, not related to tcsh).

Here is my script energy.tcsh

Code:
#! /bin/tcsh

set temp=(`getopt -s tcsh -o g:: o:: --long gaussian::,orca:: -- $argv:q`) #the space between "g::" and "o::" was included #intentionally, so this would not be replaced by a smiley icon.
if ($? != 0) then
  echo "Terminating..." >/dev/stderr
  exit 1
endif

eval set argv=\($temp:q\)

while (1)
        switch($1:q)
        case -g:
        case --gaussian:

                if ($2:q == "") then
                        set counter="*.log"
                        echo "Option GAUSSIAN" $counter
                else
                        echo "Option GAUSSIAN, argument "\`$2:q\'
                endif
                shift; shift
                breaksw

        case -o:
        case --orca:

                if ($2:q == "") then
                        set counter="*.out"
                        echo "Option ORCA" $counter
                else
                        echo "Option ORCA, argument "\`$2:q\'
                endif
                shift; shift
                breaksw
        case --:
                shift
                break
        default:
                echo "Internal error!" ; exit 1
        ends
end
It is based on https://github.com/blackberry/GetOpt...opt-parse.tcsh, the only example I could find that uses getopt in tcsh. In short:

I want to extract data (note this part is not in the script yet) from files within a directory, and these files are output produced by certain software (Gaussian or Orca). I either want the script to operate on one selected file or on all files of that type (endings are .log or .out), so I thought I try around with some options to provide this information. "-o" or "--orca" was defined for one, "-g" and "--gaussian" as the options for the other program output.

For example
./energies -o should operate on all Orca output (= .out) files present in the directory, and likewise ./energies --orca should do the same.

./energies -g or ./energies --gaussian should operate on all Gaussian output (= .log) files in the directory.

This works for any example files present.

However, when ./energies -o file.out is invoked (note the space between the option and the argument), it does not pick up the argument "file.out". When there is no space, such as in ./energies -ofile.out this works fine:

Code:
>>>./energy.tcsh -o file.out
Option ORCA one.out three.out two.out

>>>./energy.tcsh -ofile.out
Option ORCA, argument `file.out'
On a similar note, how can I pass this argument on to the long option version?
As in

./energy.tcsh --orca file.out

From the command line I currently get
Code:
>>>./energy.tcsh --orcafile.out
getopt: unrecognized option '--orcafile.out'

>>>./energy.tcsh --orca file.out
Option ORCA one.out three.out two.out
In the parent script getopt-parse.tcsh (see link) these questions refer to the -b and -c options. Why does the parsing not work for "-c more" but for -cmore. Why does --c-long 'wow\!*\?' not pick up the argument but yields --c-long without an argument. Why is the -b option flexible in this respect?

Code:
 
>>>./parse.tcsh -b hallo
Option b, argument `hallo'
Remaining arguments:

>>> ./parse.tcsh -bhallo
Option b, argument `hallo'
Remaining arguments:
I don't understand how this works for the getup command I must admit. I thought this was just controlled by the ":" (mandatory argument) and "::" (optional argument) characters in the getopt line.

How are arguments (here specifically filenames) passed on to the short (-o, -g, or -b, -c) or the long options (--orca, --gaussian, --b-long, --c-long), with or without a whitespace in between them.

I cannot see the difference in the script to be honest.

Thanks so much for your valuable input.

Kind regards

Tobias

Last edited by Tobias Kraemer; 01-30-2018 at 09:59 AM.
 
Old 01-26-2018, 02:16 PM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206
Welcome to LQ!

Please edit your post to place your code snippets inside [CODE]...[/CODE] tags for better readability. You may type those yourself or click the "#" button in the edit controls.

That is the expected behavior of getopt.

The cause of the handling for short options is because you have specified an optional argument. When parsing the input getopt has no way of knowing whether the trailing characters are an optional argument or a non-option argument, so it defaults to non-option and your script breaks out of the input loop (on --) before processing it.

You can bind the optional argument to the short option by not separating it with the space, or you can specify it as a required argument.

Similarly, but not quite exactly the same, for long arguments, getopt would not be able to tell whether --longargfilename is a long arg named --longarg followed by a filename, or if you intended it to be a long arg named --longargfilename. You must separate the name and the value by a space or an = sign: --longarg=filename. But for an optional argument the = is mandatory, otherwise it interprets the trailing characters as a non-option argument and your script breaks out of the input loop.

See man getopt for all the details. Good luck!

Last edited by astrogeek; 01-26-2018 at 04:22 PM. Reason: = not valid for short opts, more explicit loop exit on --
 
Old 01-30-2018, 09:57 AM   #3
Tobias Kraemer
LQ Newbie
 
Registered: Jan 2018
Posts: 2

Original Poster
Rep: Reputation: Disabled
Dear astrogeek,


thanks for your answer. Ok, missed a few things obviously, thanks for pointing these out. Makes much more sense now.
I've amended my previous post according to your suggestions regarding code snippets.

Best,


Tobias
 
  


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
Variable substitution (stupid noob) question in tcsh King of Men Linux - Newbie 4 12-04-2005 09:12 AM
tcsh scripting question BrianK Programming 0 04-21-2005 09:39 PM
getopt(3) Berhanie Programming 8 06-15-2004 09:50 PM
Getopt() newbie... AMMullan Programming 6 02-11-2004 01:02 PM
Using getopt in cplus UltimaGuy Programming 3 08-28-2003 05:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

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