How do I disable garbage collection messages with GNU Smalltalk 3.0.5 stable? Also, is there a way to remove the quote marks output when outputting strings?
Ex:
'test' printNl.
prints
'test'
rather than
test
Garbage collection messages are disabled automatically when you use your program as a script (i.e. with gst -f), or you can use --no-gc-message (short option -g).
printNl is a programmer-oriented printing message. To print without quotes use display/displayNl. Similarly, characters will be printed without dollar signs.
Related
SETUP: Expect/Tcl Script in Linux
USE CASE:
Using expect to wait for the report of some status to be used in a $user_command.
expect -re "notify (.+)\n"
set status $expect_out(1,string)
send [string map [list SESSION "$status"] "$user_command"]
So when the application sends "notify running", then status is set to running.
For that a keyword STATUS in $user_command needs to be replaced with $status, such that, for example
"log STATUS to file"
becomes
"log running to file"
To see what is happing, I wrote
expect_tty -re "(.+)\n"
set status $expect_out(1,string)
send_user [string map [list SESSION "$status"] "$user_command"]
which works fine when running isolatedly. The output is
log someUserInput to file
when typing someUserInput to responde to expect_tty. However, as part of a larger script, the string map command it removes anything before the string replacement, so that the output becomes
" to file"
(without a newline) I checked for the uniqueness of variables in the script, so that this is not an issue.
QUESTION:
What is going on here? How can I make the script robust?
The string map command is exactly deterministic. At each character of its input string, in order, it considers whether any of the from strings in the mapping list match, in order, and if so it performs the replacement (with the paired to string) and goes on to consider the character immediately after the replaced substring. (The empty string is a special case: it's never matched.) The code to implement it is really quite stupid, but happens to be very cache friendly on modern computers so it's still very fast; more sophisticated and supposedly “faster” implementations have been tried, but found to be slower in practice with the kinds of maps usually encountered in the wild.
If the replacement is failing to apply, it's usually because the input string is not quite what you expect. In most programs this is rare, but it's more common with expect programs because the output of the terminal emulation engine inside them can include metacharacters for things like moving the cursor around and changing the color. (Often the easiest fix for that is to tell the spawned program that its terminal type is one that doesn't support such complex features, perhaps by setting the TERM environment variable to dumb.)
Thanks to #glennjackman:
The problem is due to applications reporting newline as \r\n, so that (.*)\n in
expect_tty -re "(.+)\n"
matches in expression 1 (the thing inside the brackets) something that includes \r at the end. With \r removing anything before it, string map seems to cut anything before the replaced string. The solution is to expect something that excludes \r, i.e.
expect -re ``(\[^\r\n\]+)``
which collects anything until end of line, whatsoever the format may be.
I send a SNMPv3 Trap and separate its fields using | and ; but these characters are also appearing in my trap, which confuses my parser at trap receiving end. I also tried most of the characters e.g. :,".><!##$%^&*()
but all these single line character appear in the trap. I also tried special symbols like €,¾,½ but Linux is not accepting these characters.
I need a single character separator.
Could you suggest any Key that can be entered from from Keyboard and works in Linux?
Assignment Operator Worked =, Since it is nearly impossible of assignment operator occurring in trap content.
Some programming languages e.g. Pascal and Java have a keyword or standard library function e.g. print to output a value, and a separate name println to output with a newline, but this has the disadvantage of giving the shorter/more obvious name to the behavior you don't usually want.
Other languages e.g. Basic and Python use print for the behavior you do usually want and have a special syntax such as a trailing ; or , to suppress the newline when required. This works, but one could argue that it would be more elegant/transparent to have different names for the two behaviors.
Are there - or have there ever been - any languages where output of a value with newline is spelled print, and there is a separate name for output without newline?
Tcl's puts prints the given string and the trailing newline by default, unless it's passed the -nonewline command-line option.
How do some programs edit whats being displayed on the terminal (to pick a random example, the program 'sl')? I'm thinking of the Linux terminal here, it may happen in other OS's too, I don't know. I've always thought once some text was displayed, it stayed there. How do you change it without redrawing the entire screen?
Depending on the terminal you send control seuqences. Common sequences are for example esc[;H to send the cursor to a specific position (e.g. on Ansi, Xterm, Linux, VT100). However, this will vary with the type or terminal the user has ... curses (in conjunction with the terminfo files) will wrap that information for you.
Many applications make use of the curses library, or some language binding to it.
For rewriting on a single line, such as updating progress information, the special character "carriage return", often specified by the escape sequence "\r", can return the cursor to the start of the current line allowing subsequent output to overwrite what was previously written there.
try this shellscript
#!/bin/bash
i=1
while [ true ]
do
echo -e -n "\r $i"
i=$((i+1))
done
the -n options prevents the newline ... and the \r does the carriage return ... you write again and again into the same line - no scroling or what so ever
If you terminate a line sent to the terminal with a carriage return ('\r') instead of a linefeed ('\n'), it will move the cursor to the beginning of the current line, allowing the program to print more text over top of what it printed before. I use this occasionally for progress messages for long tasks.
If you ever need to do more terminal editing than that, use ncurses or a variant thereof.
There are characters that can be sent to the terminal that move the cursor back. Then text can be overwritten.
There is a list here. Note the "move cursor something" lines.
NCurses is a cross-platform library that lets you draw user interfaces on smart terminals.
Corporal Touchy has answered how this is done at the lowest level. For easier development the curses library gives a higher level of control than simply sending characters to the terminal.
To build on #Corporal Touchy's answer, there are libraries available that will handle some of this functionality for you such as curses/ncurses
I agree with danio, ncurses is the way to go. Here's a good tutorial:
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
If I do something like:
$ cat /bin/ls
into my terminal, I understand why I see a bunch of binary data, representing the ls executable. But afterwards, when I get my prompt back, my own keystrokes look crazy. I type "a" and I get a weird diagonal line. I type "b" and I get a degree symbol.
Why does this happen?
Because somewhere in your binary data were some control sequences that your terminal interpreted as requests to, for example, change the character set used to draw. You can restore everything to normal like so:
reset
Just do a copy-paste:
echo -e '\017'
to your bash and characters will return to normal. If you don't run bash, try the following keystrokes:
<Ctrl-V><Ctrl-O><Enter>
and hopefully your terminal's status will return to normal when it complains that it can't find either a <Ctrl-V><Ctrl-O> or a <Ctrl-O> command to run.
<Ctrl-N>, or character 14 —when sent to your terminal— orders to switch to a special graphics mode, where letters and numbers are replaced with symbols. <Ctrl-O>, or character 15, restores things back to normal.
The terminal will try to interpret the binary data thrown at it as control codes, and garble itself up in the process, so you need to sanitize your tty.
Run:
stty sane
And things should be back to normal. Even if the command looks garbled as you type it, the actual characters are being stored correctly, and when you press return the command will be invoked.
You can find more information about the stty command here.
You're getting some control characters piped into the shell that are telling the shell to alter its behavior and print things differently.
VT100 is pretty much the standard command set used for terminal windows, but there are a lot of extensions. Some control character set used, keyboard mapping, etc.
When you send a lot of binary characters to such a terminal, a lot of settings change. Some terminals have options to 'clear' the settings back to default, but in general they simply weren't made for binary data.
VT100 and its successors are what allow Linux to print in color text (such as colored ls listings) in a simple terminal program.
-Adam
If you really must dump binary data to your terminal, you'd have much better luck if you pipe it to a pager like less, which will display it in a slightly more readable format. (You may also be interested in strings and od, both can be useful if you're fiddling around with binary files.)