Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle multi-line commands #45

Open
nrvale0 opened this issue May 22, 2018 · 9 comments
Open

Handle multi-line commands #45

nrvale0 opened this issue May 22, 2018 · 9 comments

Comments

@nrvale0
Copy link

nrvale0 commented May 22, 2018

Nice package. Having a problem using it when there are single or double-quotes in either command or the comments (using commentecho: true). For instance, the following line:

vault write -format=yaml pki_root/root/generate/internal \                                                                                                                                                                           
      common_name='somefakeorg.example Root CA' \                                                                                                                                                                                                                                                                                                                                                                                      
      ttl=8760h                                                                                                                                                                                                                                                                                                                                                                               

cause the following backtrace:

Traceback (most recent call last):                                                                                                                                                                                                                                                                                                                                                                                                       
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/bin/doitlive", line 11, in <module>                                                                                                                                                                                                                                                                                                                                             
    sys.exit(cli())                                                                                                                                                                                                                                                                                                                                                                                                                      
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/click/core.py", line 722, in __call__                                                                                                                                                                                                                                                                                                               
    return self.main(*args, **kwargs)                                                                                                                                                                                                                                                                                                                                                                                                    
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/click/core.py", line 697, in main                                                                                                                                                                                                                                                                                                                   
    rv = self.invoke(ctx)                                                                                                                                                                                                                                                                                                                                                                                                                
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/click/core.py", line 1066, in invoke                                                                                                                                                                                                                                                                                                                
    return _process_result(sub_ctx.command.invoke(sub_ctx))                                                                                                                                                                                                                                                                                                                                                                              
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/click/core.py", line 895, in invoke                                                                                                                                                                                                                                                                                                                 
    return ctx.invoke(self.callback, **ctx.params)                                                                                                                                                                                                                                                                                                                                                                                       
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/click/core.py", line 535, in invoke                                                                                                                                                                                                                                                                                                                 
    return callback(*args, **kwargs)                                                                                                                                                                                                                                                                                                                                                                                                     
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/doitlive/cli.py", line 322, in play                                                                                                                                                                                                                                                                                                                 
    commentecho=commentecho)                                                                                                                                                                                                                                                                                                                                                                                                             
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages/doitlive/cli.py", line 129, in run                                                                                                                                                                                                                                                                                                                  
    command_as_list = shlex.split(ensure_utf8(command))                                                                                                                                                                                                                                                                                                                                                                                  
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/shlex.py", line 305, in split                                                                                                                                                                                                                                                                                                                                     
    return list(lex)                                                                                                                                                                                                                                                                                                                                                                                                                     
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/shlex.py", line 295, in __next__                                                                                                                                                                                                                                                                                                                                  
    token = self.get_token()                                                                                                                                                                                                                                                                                                                                                                                                             
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/shlex.py", line 105, in get_token                                                                                                                                                                                                                                                                                                                                 
    raw = self.read_token()                                                                                                                                                                                                                                                                                                                                                                                                              
  File "/home/redacted/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/shlex.py", line 206, in read_token                                                                                                                                                                                                                                                                                                                                
    raise ValueError("No escaped character")                                                                                                                                                                                                                                                                                                                                                                                             
ValueError: No escaped character                                                                                                                                                                                                                                                                                                                                                                                                         

At least in the case of comments you can avoid the backtrace by escaping the single or double quotes but then the escaping also shows up in the commentecho output.

Ideas?

@sloria sloria added the bug label May 23, 2018
@sloria
Copy link
Owner

sloria commented May 23, 2018

Thanks for reporting this. I don't have time to look into this right now, but I would certainly review and merge a PR for this.

@nrvale0
Copy link
Author

nrvale0 commented Jun 5, 2018

This is not because of the nested quoting but because of the multiline escaped commands passed to Python shlex.

@sloria sloria changed the title quote character handling Handle multi-line commands Jun 5, 2018
@sloria
Copy link
Owner

sloria commented Jun 5, 2018

Ah, good catch @nrvale0 . I've renamed the issue.

@nrvale0
Copy link
Author

nrvale0 commented Jun 5, 2018

The root issue is that the cli.py/run is reading the session one line at a time and then feeds each line to shlex.split(). In the situation where the command is multiline shlex is rightfully complaining that there's nothing following the line escape character. Some adjustments are necessary to the parsing logic in run()...seems like it should not be particularly difficult to add support for multiline.

@sparrow242
Copy link

sparrow242 commented Oct 7, 2024

Handle lines broken by '\' as one single line (on play and record) would fix the issue.
But that would lead to the behaviour that the written file will contain all parts of the ''-broken lines in a single line and if you replay a script with such broken lines they will be concated to one single line.

If that behaviour acceptable, I create a PR for that.

@sloria
Copy link
Owner

sloria commented Oct 7, 2024

@sparrow242 Can you clarify your suggestion? Do you mean that if you have

vault write -format=yaml pki_root/root/generate/internal \                                                                                                                                                                           
      common_name='somefakeorg.example Root CA' \                                                                                                                                                                                                                                                                                                                                                                                      
      ttl=8760h                                                                                                                                                                                                                                                                                                                                                                               

in your session file, that it would play back as

vault write -format=yaml pki_root/root/generate/internal common_name='somefakeorg.example Root CA' ttl=8760h                                                                                                                                                                    ```

?

@sparrow242
Copy link

sparrow242 commented Oct 8, 2024

@sloria
Exactly.
If this behavior is okay, I would have a corresponding PR.

sparrow242 added a commit to sparrow242/doitlive that referenced this issue Oct 8, 2024
Fix for:
- issue sloria#45
- issue sloria#247

Instead of sending every line directly to shlex it using a list
as a buffer for lines ending with a backslash and join them
together as one command before coninue processing.

That fixes the issue that the program dies with an exception when
a line ends with a backslash (and the quotes are note closed) but
it also leads to the behaviour that such broken lines are handle
as a single line on replay and on recording.
@nrvale0
Copy link
Author

nrvale0 commented Oct 9, 2024

Appreciate the follow-up.

I don't have the original document anymore but I can mock something that works similarly and try that out... It'll be a minute. Stand by...

@sloria
Copy link
Owner

sloria commented Oct 18, 2024

@sparrow242 I appreciate the suggestion and the PR, but I'm lukewarm on the behavior of implicitly concatenating the lines in the playback. Presumably, if you're adding a multiline command to your session file, it's because it's too long to look good on a single line, so you'd want the playback to respect the line breaks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants