2

I am working on a program that takes another command with its arguments:

$ myprog record -f 1.txt ls
$ myprog record -f 1.txt ls -l

Something like sudo:

$ sudo ls
$ sudo ls -l

Here is my code that uses cmdargs:

#!/usr/bin/env stack
-- stack --resolver lts-9.20 script --package cmdargs

{-# LANGUAGE DeriveDataTypeable #-}

module Main where

import           System.Console.CmdArgs as Args

data Tape = Record  {file :: Maybe String, command :: String, commandArgs :: [String]}
          | Replay
            deriving (Data, Typeable, Show, Eq)
main :: IO ()
main = do
  m <- cmdArgs $ modes
         [ Record  { file        = def &= typ "FILE"
                   , command     = def &= typ "COMMAND" &= argPos 0
                   , commandArgs = def &= typ "ARGS"    &= args     }
         , Replay ]
  print m

It works nicely, but only for commands that don't have their own flags:

$ ./cmdargs.hs record -f 1.txt ls
Record {file = Just "1.txt", command = "ls", commandArgs = []}

$ ./cmdargs.hs record -f 1.txt ls 1 2 3
Record {file = Just "1.txt", command = "ls", commandArgs = ["1","2","3"]}

$ ./cmdargs.hs record -f 1.txt ls -l
Unknown flag: -l

Q: How to instruct cmdargs to keep "commandArgs" as is, without looking for flags in it?

oshyshko
  • 2,008
  • 2
  • 21
  • 31

1 Answers1

3

The traditional method is not within the parser but using a -- argument, indicating the end of flags:

$ ./args record -- something -l
Record {file = Nothing, command = "something", commandArgs = ["-l"]}

Unfortunately I don't know how to tell getArgs to do so at an arbitrary place, but I imagine it would have something to do with modes.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26