Open kristi opened 12 years ago
Wow ... That's wonderful. Props. I never thought of doing that. What did you want it to do? I'm not being condescending, I'm genuinely interested. Did you think that then you could do multiline tick tick style json in the shell, interactively? That would be pretty wonderful but probably a different project.
Really though, what were trying to do?
EDIT: Crap. This is totally possible. Dear lord ... what an incredible piece of work this shell is.
Was just trying out your library. It's not unreasonable to enter commands into the interactive shell. I like to test commands manually in an interactive shell, then when things work, save them into a script file.
Ok I see. Yes, there is really no way to do that right now (not without a lot of work on my side). When you do . ticktick.sh
It actually uses a debugging feature to find out the file that you are including it from.
Then it reads the contents of your script. It replaces the back ticks with valid bash. You can see this by setting __tick_var_debug=1 at the top of your script, before the include.
For instance, the example script
#!/bin/bash . ticktick.sh bob=Bob `` people = { "HR" : [ "Alice", $bob, "Carol" ], "Sales": { "Gale": { "profits" : 1000 }, "Harry": { "profits" : 500 } } } `` function printEmployees() { echo echo " The ``people.Engineering.length()`` Employees listed are:" for employee in ``people.Engineering.items()``; do printf " - %s\n" "${!employee}" done echo } echo Base Assignment `` people.Engineering = [ "Darren D", "Edith E", "Frank F" ] `` printEmployees newPerson="Isaac I" echo Pushed a new element by variable, $newPerson onto the array `` people.Engineering.push($newPerson) `` printEmployees echo Shifted the first element off: `` people.Engineering.shift() `` printEmployees echo Popped the last value off: `` people.Engineering.pop() `` printEmployees echo Indexing an array, doing variable assignments person0=``people.HR[0]`` echo $person0 ``people.HR[1]``
If you put that variable in there and then run it you'll get this:
#!/bin/bash __tick_var_debug=1 . ticktick.sh bob=Bob __tick_data_people_HR_000000000000="Alice" __tick_data_people_HR_000000000001=$bob __tick_data_people_HR_000000000002="Carol" __tick_data_people_Sales_Gale_profits=1000 __tick_data_people_Sales_Harry_profits=500 function printEmployees() { echo echo " The `__tick_runtime_length ${!__tick_data_people_Engineering_*}` Employees listed are:" for employee in ${!__tick_data_people_Engineering_*}; do printf " - %s\n" "${!employee}" done echo } echo Base Assignment __tick_data_people_Engineering_000000000000="Darren D" __tick_data_people_Engineering_000000000001="Edith E" __tick_data_people_Engineering_000000000002="Frank F" printEmployees newPerson="Isaac I" echo Pushed a new element by variable, $newPerson onto the array __tick_runtime_push "$newPerson" __tick_data_people_Engineering_ ${!__tick_data_people_Engineering_*} printEmployees echo Shifted the first element off: `__tick_runtime_first ${!__tick_data_people_Engineering_*}`; __tick_runtime_shift ${!__tick_data_people_Engineering_*} printEmployees echo Popped the last value off: "$( __tick_runtime_last ${!__tick_data_people_Engineering_*} )"; __tick_runtime_pop ${!__tick_data_people_Engineering_*} printEmployees echo Indexing an array, doing variable assignments person0=${__tick_data_people_HR_000000000000}
Basically your script gets totally rewritten by ticktick based on what you have in the back ticks, then the new code gets executed and the script stops parsing there.
That means that bash never tries to execute the real script that you wrote with the backticks because including ticktick basically hijacks the shell, makes a copy of your script in memory, rewrites it into valid bash, executes the rewritten in-memory version of your program and then exits.
This is possible because unlike in a compiled language such as C, bash only reads one line at a time. So it will execute your script line by line until either their are no lines left, it's told to exit, or it sees something it doesn't recognize and then exits with an error.
Normally, the tick tick syntax would be in the third group and bash would not go on. But because we tell it to exit, inside the first line of the program, inside of the ". ticktick.sh", that means that it never really "sees" the original, invalid, tick-tick style bash code. It's a wonderful little trick. I got the inspiration from CoffeeScript.
So it's very dependent on files and scripts. To do this inline is quite possible but I assure you, an even more difficult feat.
If you want to, you can use an inotify tool that will detect when your script gets written to disk and then executes it immediately. That's probably the closest thing you could do to get there without me writing this theoretical interactive shell hijacker (which sounds mighty scary)
@kristopolous wrote:
because including ticktick basically hijacks the shell, makes a copy of your script in memory, rewrites it into valid bash, executes the rewritten in-memory version of your program and then exits.
Ahem in memory, you say?
I think it only does it in memory for the main script that sourced ticktick.sh.
Anything that script subsequently sources, seems to get written to a file in /tmp, with a name like /tmp/ymrjibble.skibble
(though usually without the rhyming). Whether or not TickTick has to make any changes to that file.
At least, that's my understanding from the increasing number of files hanging out under /tmp, and the periodic errors like Missing ] on line 52 of /tmp/blahbloh.blih
.
That said, nice post, and brilliant project!
Initializing ticktick in an interactive bash shell causes the shell to hang
The source command doesn't complete. It just hangs.