TickTick icon indicating copy to clipboard operation
TickTick copied to clipboard

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

Open Artoria2e5 opened this issue 4 years ago • 16 comments

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 <<<.

Artoria2e5 avatar May 10 '20 11:05 Artoria2e5

hey that's pretty clever. good work.

kristopolous avatar May 21 '20 19:05 kristopolous

isn't <<< a bashism?

kristopolous avatar May 21 '20 19:05 kristopolous

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

kristopolous avatar May 21 '20 19:05 kristopolous

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

kristopolous avatar May 21 '20 19:05 kristopolous

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

kristopolous avatar May 21 '20 19:05 kristopolous

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 avatar May 21 '20 19:05 kristopolous

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 ...

kristopolous avatar May 21 '20 19:05 kristopolous

isn't <<< a bashism?

Yes.

http://mywiki.wooledge.org/HereDocument?action=show&redirect=HereString

XLTechie avatar May 21 '20 21:05 XLTechie

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.

Artoria2e5 avatar May 22 '20 02:05 Artoria2e5

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 avatar May 25 '20 15:05 kristopolous

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 avatar May 25 '20 15:05 kristopolous

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 avatar May 25 '20 16:05 kristopolous

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

kristopolous avatar May 25 '20 16:05 kristopolous

Something I have wondered:

It claims to let you put JSON in bash scripts. When did it decide it had to support every bash varient on the planet?

Let it be bash.

You never claimed it supported dash, busybox, korn, or aunt Fanny's shhhh.

On Mon, 25 May 2020, chris mckenzie wrote:

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 avatar May 27 '20 06:05 XLTechie

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

Artoria2e5 avatar May 28 '20 14:05 Artoria2e5

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.

ewildgoose avatar Jan 29 '21 17:01 ewildgoose