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

"Portable" (no debug magic) mode using HERE-documents (<<'EOF') #44

Open
Artoria2e5 opened this issue May 10, 2020 · 16 comments
Open

"Portable" (no debug magic) mode using HERE-documents (<<'EOF') #44

Artoria2e5 opened this issue May 10, 2020 · 16 comments

Comments

@Artoria2e5
Copy link

Artoria2e5 commented May 10, 2020

A lot of people are requesting ticktick for some other shell xsh where debug facilities may be nonexistent. A way to get that job done is to write a function that reads from its stdin, transpiles the code, and runs eval -- no caller magic needed! It's going to work in interactive shells too!

# The function should look like this...
tt() {
  eval "$(__tick_fun_tokenize_expression | __tick_fun_parse_expression)"
}
# don't ask me about disabling the rest of the magic i don't know okay?

People can then write blocks of JSON for that in here-documents and one-line here-strings. They are a bit more tedious, but that is expected. For example, instead of the example, we can say:

#!/bin/bash
TICKTICK_NOMAGIC=1
. ticktick.sh

bob=Bob
tt <<'EOF'
  people = {
    "HR" : [
      "Alice",
      $bob,
      "Carol"
    ],
    "Sales": {
      "Gale": { "profits" : 1000 },
      "Harry": { "profits" : 500 }
    }
  }
EOF

function printEmployees() {
  echo
  echo "  The $(tt <<< 'people.Engineering.length()') Employees listed are:"

  for employee in $(tt <<< 'people.Engineering.items()'); do
    printf "    - %s\n" ${!employee}
  done

  echo 
}

echo Base Assignment
tt <<< 'people.Engineering = [ "Darren", "Edith", "Frank" ]'
printEmployees

newPerson=Isaac
echo Pushed a new element by variable, $newPerson onto the array
tt <<< 'people.Engineering.push($newPerson)'
printEmployees

echo Shifted the first element off: $(tt <<< 'people.Engineering.shift()')
printEmployees

echo Popped the last value off: $(tt <<< 'people.Engineering.pop()')
printEmployees

echo Indexing an array, doing variable assignments

person0=$(tt <<< 'people.HR[0]')
echo $person0 $(tt <<< 'people.HR[1]')

(Note the quotes on EOF -- that prevents the shell from expanding $bob on its own prematurely. And the quotes on (), because when they poke out they make a syntax error. The quotes on [0] is there because it can mean a glob, and you don't want to risk having a file called people.HR0 and messing this up.)


  • If you are going interactive, you can even type tt, paste stuff in, and Ctrl-D it. The possibilties are limitless!
  • People can put positional arguments in by calling tt as tt "$@", although I don't see much use for that. If they really want that, they can make an alias tta='tt "$@"' and make it work in scripts with shopt -s expand_aliases. (Aliases are wonderful; they are like macros for bash, lmao.)
  • We can write another function ttl() { printf %s "$1" | tt "${@:2}"; }, just for typing less <<<.
@kristopolous
Copy link
Owner

hey that's pretty clever. good work.

@kristopolous
Copy link
Owner

isn't <<< a bashism?

@kristopolous
Copy link
Owner

for instance, dash, from busybox doesn't have it:
Redirection operators:
< > >| << >> <& >& <<- <>

@kristopolous
Copy link
Owner

nor does the old as dirt CSH
|| && | ^ & == != =~ !~ <= >=
< > << >> + - * / % ! ~ ( )

@kristopolous
Copy link
Owner

don't get me wrong, I love the hack but it doesn't fix the dash/csh/ksh/tcsh problem

@kristopolous
Copy link
Owner

I also don't really understand why jq and the more serious programs like that aren't alternatives ... maybe you can tell me ... what's your actual usecase?

@kristopolous
Copy link
Owner

kristopolous commented May 21, 2020

I mean the real real real way to do this would be to just jack the interpreter as a fat wacky wrapper ... essentially have a program say, /usr/bin/crash that does all the intepreter stuff and then do this

#!/usr/bin/crash
... proceed as usual ...

@XLTechie
Copy link
Contributor

XLTechie commented May 21, 2020 via email

@Artoria2e5
Copy link
Author

Artoria2e5 commented May 22, 2020

Yeah, that's a bashism. printf %s "somestuff" | tt can be used to go around it though. It might be available in some version of ksh, but I am not sure.

CSH is out of the question: the syntax isn't even in the same family of POSIX/Bourne shells. And then there's that one epic rant about how awful CSH is for programming called CSH programming considered harmful.

@kristopolous
Copy link
Owner

I was in the space between sleep and awake this morning when I had more visions of the crash system ... essentially we'll need to either permanently do portable syntax (like '[' instead of '[[') or have a converter. The '[[' is sooo much faster ...

A bash-4 -> POSIX SH transpiler sounds like something that probably already exists in the world - I took enough of computer theory to know it's possible to completely make this since POSIX SH is tightly bound ... It's been around for 31 years I bet this exists. Let me look

@kristopolous
Copy link
Owner

hrmm ... "checkbashism" and "shellcheck" are the internet recommendations ... that's lame. I want to have a magic converter as part of a build script.

@kristopolous
Copy link
Owner

kristopolous commented May 25, 2020

I dunno ... I think I'll just ask stackexchange ... https://unix.stackexchange.com/questions/588862/is-there-a-bash-to-posix-transpiler let's see what happens.

edit: Apparently the silly doofuses at stackoverflow are uninformed dorks ... I don't have time to run a shell bootcamp for the supposed experts there. I'll do it myself.

@kristopolous
Copy link
Owner

about 8 years ago, I was asked for busybox dash support in #22 and that should probably be the reference interpreter here. There's sadly quite a bit of hacks that would need to be done. bash's string substitution in a variable for instance (${//}) doesn't seem to be there.

Unless I want this thing to crawl I think I'd have to rewrite chunks of it more heavily in awk and sed

@XLTechie
Copy link
Contributor

XLTechie commented May 27, 2020 via email

@Artoria2e5
Copy link
Author

One of the things for magic-less even in bash is usability in an interactive shell. That's #20.

@ewildgoose
Copy link

bash's string substitution in a variable for instance (${//}) doesn't seem to be there.

I'm just checking my busybox shell right now and this works:

$ stringZ=abcABC123ABCabc; echo ${stringZ/abc/xyz}
xyzABC123ABCabc

Does this get us any further forward? The main thing we can't do with busybox is arrays.

I would love to get this working with my busybox systems so I can use it for simple config files. Nothing more than some fields with product type, version, etc. For various reasons it's helpful to have them in json.

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

No branches or pull requests

4 participants