• Re: How to enter escape character in a positional string argumentfrom t

    From Chris Angelico@21:1/5 to gene heskett on Thu Dec 22 04:00:44 2022
    On Thu, 22 Dec 2022 at 03:58, gene heskett <gheskett@shentel.net> wrote:

    On 12/21/22 11:22, Chris Angelico wrote:
    On Thu, 22 Dec 2022 at 03:11, Stefan Ram <ram@zedat.fu-berlin.de> wrote:

    Lars Liedtke <lal@solute.de> writes:
    Or you could have "native" bash ($SHELL) with WSL.

    In this newsgroup, it would actually be obvious to use Python.

    Less obvious than you might think - partly because bash is just so
    dang good that it's really really hard to outdo it :) Sure, bash has a
    lot of weird and wonky edge cases, but it's an incredibly practical
    shell to use.

    When you make a statement like that, Chris, you should also note that
    every single one of those "wonky edge cases" is documented down to the
    last dotted i. Bash's docs will kill a good sized pulp tree, needing
    around a ream of paper to print on a duplex printer. I know, I did it
    around a decade ago. If you like to write scripts, having a dead tree
    copy of the docs at your elbow in incredibly useful. That huge man page
    does not cover it like the printed docs do.


    Oh yes, absolutely true. Its wonkiness is dependable and consistent;
    but it is definitely quirky (look at all the different ways to embed
    arguments into things, and the ways that $*, $@, "$*, and "$@" behave
    when put into variables). Not usually a problem, but it does sometimes
    leave you thinking "wow, wouldn't it be easier to just use something
    like Python?". And in the complicated cases, yeah, it can be. But in
    the simple cases? Bash rocks.

    ChrisA

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gene heskett@21:1/5 to Chris Angelico on Wed Dec 21 11:55:54 2022
    On 12/21/22 11:22, Chris Angelico wrote:
    On Thu, 22 Dec 2022 at 03:11, Stefan Ram <ram@zedat.fu-berlin.de> wrote:

    Lars Liedtke <lal@solute.de> writes:
    Or you could have "native" bash ($SHELL) with WSL.

    In this newsgroup, it would actually be obvious to use Python.

    Less obvious than you might think - partly because bash is just so
    dang good that it's really really hard to outdo it :) Sure, bash has a
    lot of weird and wonky edge cases, but it's an incredibly practical
    shell to use.

    When you make a statement like that, Chris, you should also note that
    every single one of those "wonky edge cases" is documented down to the
    last dotted i. Bash's docs will kill a good sized pulp tree, needing
    around a ream of paper to print on a duplex printer. I know, I did it
    around a decade ago. If you like to write scripts, having a dead tree
    copy of the docs at your elbow in incredibly useful. That huge man page
    does not cover it like the printed docs do.

    When commands are typed manually, this might be a bit verbose,
    though. I mean

    os.chdir( r'C:\EXAMPLE' )

    versus

    CD C:\EXAMPLE

    Exactly. What's good for a programming language is often not good for a shell.

    class PythonShell( cmd.Cmd ):

    intro = 'Welcome to the Python shell. Type help or ? to list commands.\n'
    prompt = '(Python) '
    file = None

    def do_cd( self, arg ):
    'change directory: CD C:\EXAMPLE'
    os.chdir( *parse( arg ))

    def do_bye( self, arg ):
    'Exit: BYE'
    print( 'Thank you for using the Python Shell!' )
    return True

    Sure, you can always create your own shell. But I think you'll find
    that, as you start expanding on this, you'll end up leaning more
    towards "implementing bash-like and/or cmd-like semantics in Python"
    rather than "creating a Python shell". Shells, in general, try to
    execute programs as easily and conveniently as possible. Programming languages try to stay inside themselves and do things, with subprocess spawning being a much less important task.

    Fun challenge: see how much you can do in bash without ever forking to another program. And by "fun", I mean extremely difficult, and by
    "challenge" I really mean "something you might have to do when your
    system is utterly hosed and all you have available is one root shell".

    It's amazing how far you can go when your hard drive has crashed and
    you desperately need to get one crucial login key that you thought you
    had saved elsewhere but hadn't.

    ChrisA

    Cheers, Gene Heskett.
    --
    "There are four boxes to be used in defense of liberty:
    soap, ballot, jury, and ammo. Please use in that order."
    -Ed Howdershelt (Author, 1940)
    If we desire respect for the law, we must first make the law respectable.
    - Louis D. Brandeis
    Genes Web page <http://geneslinuxbox.net:6309/>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Angelico@21:1/5 to Barry on Thu Dec 22 04:16:47 2022
    On Thu, 22 Dec 2022 at 04:12, Barry <barry@barrys-emacs.org> wrote:
    I see bash scripts that are 1000’s of line of code at work and its a maintenance nightmare.

    Knowing when to make the move from “handy bash script” to “this is a production application” and needs to be python is what I see people miss.

    After a certain point in complexity the python code wins on maintenance. Personally i set a low bar to move from bash to python.

    Agreed 100%. However, how many commands do you type a day at the bash
    prompt? *Every one of those* is a simple case that doesn't need
    Python. That's what makes bash such a great shell. You can type
    simple, convenient commands, and they *just work*. Need something a
    bit more complicated? You can do that too. Want to automate a short
    sequence of commands? Don't have to translate them into another system
    (like Python subprocess calls), just copy/paste them into a shell
    script.

    Yes, there absolutely is a point beyond which it's better to translate everything. But the vast number of commands executed every day? Most
    of them are fine with bash. And that's why Python will never replace
    bash as a shell.

    ChrisA

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to gene heskett on Wed Dec 21 17:38:54 2022
    gene heskett <gheskett@shentel.net> writes:
    When you make a statement like that, Chris, you should also note that
    every single one of those "wonky edge cases" is documented down to the
    last dotted i.

    The Windows' cmd is wonky too, but not well documented.
    For one example: The circumflex "^" can continue a command line.
    But when one wants to use a literal circumflex "^" in a cmd
    file or in a file name, it has to be escaped in ways that
    seem to be quite irregular. This has been documented by
    amateurs, but not by Microsoft AFAIK. (Search for "Note that
    the phases described below are only a model of how the batch
    parser works.".)

    Here's a Windows cmd command file I wrote:

    ffmpeg -i "source^^.mp4" ^
    "target^^^^.mkv"

    . The actual source and target file names are supposed to be
    "source^^.mp4" and "target^^.mkv", but in the line continuation,
    the "^" has to be escaped, while in the first line it has not!

    (Ffmpeg is another piece of software with quite complex options.)

    The following Windows cmd file creates three files "aa.txt",
    "a^a.txt" and "a^^a.txt" with a delay of one minute between
    each creation. Then it loops through the directory and prints
    some stats about the files. All the fuss with the "SET" command
    is only necessary to correctly iterate through files in a
    directory in the presence of the possibility that file names
    may contain the circumflex "^"! (Warning: The script will
    overwrite some files in the directory it is executed in as
    indicated by the use of ">" below". The file has been edited
    in the newsreader before posting it and was not tested again
    after that editing took place.)

    echo 11111>aa.txt
    timeout 62
    echo 222222>a^^a.txt
    timeout 62
    echo 3333333>a^^^^a.txt

    dir *.txt

    setlocal enabledelayedexpansion
    for /f %%i in ('dir /b *.txt') do (
    SET "a=%%i"
    SET "b=!a:^=^^!"
    call :sub !b!
    )
    goto :eof

    :sub
    SET "A=%1"
    SET "B=%1"
    SET "a=%a:^=^^%"
    call :suba %A%, %B%
    goto :eof

    :suba
    echo.&echo.
    echo The file %1 was created on %~t2 and contains %~z2 bytes.
    echo Contents:
    type %1
    goto :eof

    And this script only handles the special character "^".
    There may be other characters that also require special
    handling. (I wrote the above script after someone asked
    in another Newsgroup how to do this.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry@21:1/5 to All on Wed Dec 21 17:12:47 2022
    On 21 Dec 2022, at 17:06, Chris Angelico <rosuav@gmail.com> wrote:

    On Thu, 22 Dec 2022 at 03:58, gene heskett <gheskett@shentel.net> wrote:

    On 12/21/22 11:22, Chris Angelico wrote:
    On Thu, 22 Dec 2022 at 03:11, Stefan Ram <ram@zedat.fu-berlin.de> wrote: >>>>
    Lars Liedtke <lal@solute.de> writes:
    Or you could have "native" bash ($SHELL) with WSL.

    In this newsgroup, it would actually be obvious to use Python.

    Less obvious than you might think - partly because bash is just so
    dang good that it's really really hard to outdo it :) Sure, bash has a
    lot of weird and wonky edge cases, but it's an incredibly practical
    shell to use.

    When you make a statement like that, Chris, you should also note that
    every single one of those "wonky edge cases" is documented down to the
    last dotted i. Bash's docs will kill a good sized pulp tree, needing
    around a ream of paper to print on a duplex printer. I know, I did it
    around a decade ago. If you like to write scripts, having a dead tree
    copy of the docs at your elbow in incredibly useful. That huge man page
    does not cover it like the printed docs do.


    Oh yes, absolutely true. Its wonkiness is dependable and consistent;
    but it is definitely quirky (look at all the different ways to embed arguments into things, and the ways that $*, $@, "$*, and "$@" behave
    when put into variables). Not usually a problem, but it does sometimes
    leave you thinking "wow, wouldn't it be easier to just use something
    like Python?". And in the complicated cases, yeah, it can be. But in
    the simple cases? Bash rocks.

    I see bash scripts that are 1000’s of line of code at work and its a maintenance nightmare.

    Knowing when to make the move from “handy bash script” to “this is a production application” and needs to be python is what I see people miss.

    After a certain point in complexity the python code wins on maintenance. Personally i set a low bar to move from bash to python.

    Barry



    ChrisA
    --
    https://mail.python.org/mailman/listinfo/python-list


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Stefan Ram on Wed Dec 21 18:11:13 2022
    ram@zedat.fu-berlin.de (Stefan Ram) writes:
    echo 11111>aa.txt
    timeout 62
    echo 222222>a^^a.txt
    timeout 62
    echo 3333333>a^^^^a.txt

    dir *.txt

    setlocal enabledelayedexpansion
    for /f %%i in ('dir /b *.txt') do (
    SET "a=%%i"
    SET "b=!a:^=^^!"
    call :sub !b!
    )
    goto :eof

    :sub
    SET "A=%1"
    SET "B=%1"
    SET "a=%a:^=^^%"
    call :suba %A%, %B%
    goto :eof

    :suba
    echo.&echo.
    echo The file %1 was created on %~t2 and contains %~z2 bytes.
    echo Contents:
    type %1
    goto :eof

    A similar Python script might be longer, but it deals with
    getting the job done and not with fighting irregularities.
    (Warning: This script may create/overwrite/delete files!)

    import datetime
    import pathlib
    import time

    for content, name in\
    ( ( '11111', 'aa.txt' ),( '222222', 'a^a.txt' ), ( '3333333', 'a^^a' )):
    with open( name, "w" ) as stream:
    print( content, file=stream )
    time.sleep( 62 )

    for file in pathlib.Path.cwd().glob( '*.txt' ):
    print( 'The file '+ str( file )+' was created on '+
    str( datetime.datetime.fromtimestamp( file.stat().st_ctime ))+
    ' and contains '+ str( file.stat().st_size )+' Bytes. ' )
    print( 'Contents:' )
    with open( file, 'r' )as stream: print( stream.read() )

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)