Go back up a line in a linux console?
I know I can go back the line and overwrite its contents with \r
.
My goal is to create some self-refreshing multiline console app w开发者_运维知识库ith PHP.
Use ANSI escape codes to move the cursor. For example: Esc [ 1 F
. To put the Escape character in a string you'll need to specify its value numerically, for example "\x1B[1F"
As sujoy suggests, you can use PHP ncurses for a more abstract way to move the cursor.
Whilst most "consoles" allow ANSI escape codes, other sorts of terminal use different character sequences, ncurses
provides a standardised API that is terminal independent. Have a quick look at /etc/termcap
(and then man terminfo
) if you are interested.
Update: Lars Wirzenius' answer has a useful summary of the background. Some years ago I also wrote a short article on terminals.
The Linux virtual consoles emulate an old-time display terminal, although not perfectly. See Wikipedia on VT-100 for an example of the hardware.
These terminals read data from a serial port, and displayed it on the screen. They also looked for special bytes in the input stream from the serial port and acted upon them in other ways. For example, the newline character ('\n', byte value 10) would go to the beginning of the next line, and the carriage return character ('\r', byte value 13) would go the beginning of the current line.
More interestingly, an ASCII ESC byte (27) would start a command sequence which could to almost anything to the cursor or display. One such sequence might move the cursor to the top left of the screen, another to a given row and column. A third one might clear the screen, and a fourth one might make text be displayed in reverse colors.
Every manufacturer of terminals would invent their own command sequences (and they didn't always start with ESC either), and then change them depending on what they could make new versions of their hardware do. If a manufacturer added colors or simple graphics, those resulted in new sequences.
Adapating every application to every terminal and every change to the command sequences would have been a big task. Compare it with adapting every web application to a new browser version.
As usual, the solution is to add a layer of abstraction. In Unix, the initial abstraction was called termcap
, and consisted of the file /etc/termcap
, and a library to read the file. The file would specify the actual command sequences to send for each logical operation for each terminal model. So a vt102
terminal model would map the operation "clear the screen" to the \033[2J
. This allowed application programmers to think in terms of the logical operations, which was much simpler.
Of course, not simple enough... The termcap library was not as good as it might have been, so two other libraries were developd: curses
provided a higher abstraction level, including user input, and terminfo made the terminal definitions and their use by programmers easier.
In modern times, ncurses
is a free re-implementation of curses
and terminfo
has pretty much replaced termcap
completely. Also, ANSI has defined some "standard" sequences, based on the Digital terminals, and almost every terminal emulator uses those, at least mostly, and the Linux virtual console is one of them. Very few people have actual physical terminals anymore.
For what you're trying to do, ncurses
or the tput
command may be most useful. Or you may decide that just clearing the whole screen (see clear
(1)) and writing output then is easiest.
My goal is to create some self-refreshing multiline console app with PHP
For what you are trying to achieve ncurses
is the way to go.
You shoud read about ncurses. In shell, you can go one line up by:
tput cuu1
See man terminfo
for more options.
But executing shell command to move cursor around is quite desperate.
You just you the up and down arrows on the keyboard to scroll through console history but there is also the history command. Find out more using man history
精彩评论