Print text to shell without advancing buffer - c

I would like to know if there is a way to print text into shell's current buffer/cursor so it can be edited. I am building a program that will store some text values in memory and need a simple way to edit them in the shell without rewriting the whole value. So somehow referencing the current edit buffer in shell and printing to it would be quite nice.
However, I am only using common sense here. Maybe it is more complicated. Looking forward to possible solutions.

Every shell handles user input differently. If there is an "edit buffer", it is most likely to be implemented in the shell itself. (Linux terminals do have a primitive line-editing function but as far as I know, there's no way to inject data into the line. However, only very primitive shells rely on native line-editing.)
So the question must be asked with respect to some specific shell.
Just in case, here's the answer for bash.
Bash relies on the readline library to perform command input from a terminal(-like) standard input. (Command-line history is provided using a related history library.) These libraries have a lot of features and bash does not provide access to all of them; if necessary, you could write a program in C or some scripting language with a readline binding.
But bash does give you the tools necessary to preload input with a line of text. The standard way of collecting input from a shell script is through the read command, which is (almost) always a shell "built-in". Basic ooeration of read is defined by the Posix standard, but the bash version provides a lot of useful extension options, including:
-e: use the readline library (with tab-completion, history and line editing enabked).
-i text: if readline is being used, preload readline's edit buffer with the specified text.
The
bash manual has lots more information about the read command's options.

Related

save and clear terminal window in linux [duplicate]

I'm having a hard time even googling this, because I don't know the right keywords. Some command-line apps (such as vi and less) take over the whole console screen and present an interactive interface to the user. Upon exiting such an app, the screen is returned to the state it was in before the app was launched. I want to write a program that behaves in this fashion, but again, I don't even know what this is called, so I can't find any documentation for how it's accomplished.
So, my question is threefold:
What keywords can I use to find documentation on this?
If you are so inclined, links to such documentation would be helpful.
Lastly, can I accomplish this in a scripting language like Ruby, or even bash? I have no problem with C, but the environment I work in is more amenable to interpreted languages.
As said in some comments, you are looking for ncurses. The Linux Documentation Project have a very good HOWTO on ncurses for C that I used myself to start on it
https://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
The feature you are describing is the alternate screen buffer. I think that [N]Curses will enable this by default. There are certainly curses bindings for Ruby, Python, and other scripting languages.
you can even access ncurses in bash by using the tput program. The whole ncurses library (like curses before it) works by sending escape sequences to the terminal. The xterm program emulates a vt100 terminal (and also a Tektronic terminal) and there were various combinations of characters which would move the cursor, clear the screen, draw various characters etc. These would generally start with an escape character, hence the name: escape sequence. You also sometimes see these escape sequences in people's PS1 shell variables with the \e to provide the escape character; often used to colour the prompt or set the window title.
tput refers to the terminfo database to figure out what the escape sequences are to perform the functions you've asked it to do.
see the manual page, type:
man 5 terminfo
for more details

Linux shell pipe syntax

I am implementing a program that simulates the Linux shell and I need to implement expressions with multiple pipes - but I am not sure what's considered legal or how to handle a few things, for example:
Is pipe as the last character in the command legal? When I try it in the Linux shell it displays really weird behavior - after pressing enter it shows a new line with > in the beginning. I am not sure what does this mean as to the legality of the command?
How to handle several consecutive pipes? For example ls -l ||||| grep 7
it seems the shell just works as usual and ignores the redundant pipes but I am nit sure. Would like some help.
There is not a single Linux shell (but several shells). The most common one is GNU bash, but you can use some other like zsh (which I am using interactively) or fish, or even scsh -or es- which has a quite different syntax. And all of them don't share exactly the same syntax and don't report the same errors.
There is however a standard, POSIX, which defines the POSIX shell specification (as a technical document in English):
The format for a pipeline is:
[!] command1 [ | command2 ...]
The standard output of command1 shall be connected to the standard input of command2.
As you can see, you can't end your command with a |.
Your interactive bash shell is giving a different prompt when an incomplete line has been input. It is using the GNU readline library for interactive editable input (and completion).
All the shells I know on Linux are free software, so you could study their source code. sash is a quite simple shell whose code is quite readable (but a bit buggy); it lacks most of the interactive facilities (notably auto-completion) of more sophisticated shells.
You'll need to understand most of Advanced Linux Programming before coding your own shell...
For a homework, you probably can afford giving an error message on the first encountered error.

How to display a custom prompt during the execution of C program?

I'm trying to emulate a terminal using a C program in Linux and need my program to display a custom prompt while the program executes. Is there a way to display it using my C program? (I can always try to printf "My-prompt" every line manually, but I'm looking for a better way). Also I can't use any additional libraries other than the basic ones so GNU Readline library and editline library wouldn't work (as suggested in another thread).
for example:
user#mypc:~$ ./a.out
my_custom_prompt>3+5
my_custom_prompt>8
my_custom_prompt>exit
user#mypc:~$
I believe what the OP wants is to simply have the "prompt" printed along with any program output, without having to add this manually every time. There is a way to do this, if you write a wrapper function on top of printf to do this, and call that instead of printf directly.
Probably this will help: http://www.ozzu.com/cpp-tutorials/tutorial-writing-custom-printf-wrapper-function-t89166.html
In your example, you already have got a terminal. You want to write a command-line interface with a prompt, not a terminal.
I can always try to printf "My-prompt" every line manually, but I'm looking for a better way
There’s nothing wrong with this approach. You have a loop which prints the prompt and waits for input afterwards. As Kunerd said in the comment, one line of code.
Normally, a prompt is printed to stderr rather than stdout. This has the advantage, that the prompt appears before a newline is written, as stderr is unbuffered (and in combination with piping and redirection it seems reasonable to me, that this stuff doesn’t go to the same stream as the actual output).
Also I can't use any additional libraries other than the basic ones so GNU Readline library and Editline library wouldn't work
Doing this in a way strictly conforming to the C standard and not using any libraries but the standard one makes things like line editing (other than using backspace) or a command history (close to) impossible. If that’s OK for you, look for fgets etc. and keep in mind, that stdin is usually line-buffered.
POSIX specifies some additional properties of terminals, see e.g. http://pubs.opengroup.org/onlinepubs/9699919799/. Maybe curses is also of interest for you.
Perhaps you're looking for fgets() documentation?

preventing arrow keys's outputing raw characters like ^[[A when making a shell in C

I am implementing a shell-like program where user types command (defined by me). Just like this.
>cmd
result blah blah blah
>
When I use arrow keys it outputs raw characters like ^[[A.
>^[[A
I also notice sqlite3 behaves like this at least in the version I compiled on my computer.
How to prevent this and let <- and -> keys move cursor left and right?
GNU Readline is a library specifically designed for this task (that is, allowing the user to edit commands typed at an interactive command-driven program). Note that this library is distributed under the GPL (not the LGPL); if that won't work for you, editline is a similar library with a BSD-style license.
I note that you say this is homework, so you might want to ask your instructor whether you are expected to implement cursor motion and line editing yourself. If so, ncurses (as mentioned by jDourlens) is the next step down in terms of abstraction, and if you really want to do everything yourself, read up on termios and the VT-220 control sequences (nearly all terminal emulators used nowadays emulate the VT220 or one of its descendants).
I have found a slightly simpler way to do that. Run rlwrap [your program] instead of [your program].
For example, it works fine with sqlite3 as rlwrap sqlite3
To let the user navigate in cmd with the keyboards arrows you may have to use termcaps.
http://www.gnu.org/software/termutils/manual/termcap-1.3/html_chapter/termcap_2.html
If you want to be easier to deal with termcaps that are a bit complex you shoul use Ncurses.
http://www.gnu.org/software/ncurses/ncurses.html
Good luck to deal with termcaps if you chosse this solution, it's some pain in the ass!
You may take a look to Ncurses. It's a library that let you control almost everything in terminals. The specific function you want is noecho(), which stops terminals from showing users' input.

How to implement a "text editor" style interface on terminal using c

I'm not trying to make a text editor yet. What I want to do now is simpler. It will be a command line tool (either Linux or windows). When you execute it, the user shall see a cleared terminal area, like you try to create a new file using vi.
The user can then type in some pre-defined command. Question: how to define where the user inputs? Say like what vi does, at the bottom of the terminal screen?
According to the command the user typed in, some info or figure will be shown/drawn on the screen.
The user can type in command at any time, the result will be output immediately.
The difficulty for me is how to implement such an input/output interface. Comment if there is anything not clear.
The C standard "per se" doesn't define anything for this task, for what it is concerned the terminal is "just like a file" - two (three counting stderr) streams of data, that's it.
To use the terminal in a more advanced way you have to use platform-specific methods, be them ioctl calls or VT* escape sequences. But more probably you'd better use a higher level library that handles all the low-level fuss and lets you focus on more important stuff, the classical one is ncurses.

Resources