How to write a terminal program that I can pipe the input into it?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Returrning my thoughts to the original question...
Quote:
Originally Posted by peonerovv
I want to write a simple terminal program (I'm on linux, if that's important), that will be able to take a piped input. What I mean is the same thing grep does.
...
I want to be able to fetch an input into my program with the pipe (|) symbol and then give arguments that will manipulate what the program does to the input. C will work just fine for it.
In C it is simply a matter of reading input from the *FILE stream named stdin. When stdio.h is included, stdin is always available when a C program starts so you don't have to do anything special to read from it. From man stdin:
Code:
NAME
stdin, stdout, stderr - standard I/O streams
SYNOPSIS
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
DESCRIPTION
Under normal circumstances every UNIX program has three streams opened for it when it starts up,
one for input, one for output, and one for printing diagnostic or error messages. These are typi‐
cally attached to the user's terminal (see tty(4)) but might instead refer to files or other de‐
vices, depending on what the parent process chose to set up. (See also the "Redirection" section
of sh(1).)
Here is a simple example which will prepend line numbers to anything sent via stdin:
Code:
#include <stdio.h>
#include <stdlib.h>
int main(){
int lcount = 0;
char *line = NULL;
size_t len = 0;
while (getline(&line, &len, stdin) >= 0)
{
printf("%d: %s", ++lcount, line);
free(line);
line = NULL;
}
return 0;
}
You can easily adapt that to perform whatever action you desire with the input stream.
You can do this more easily using a shell script as well. Once again, stdin is always availlable and is the default input for most purposes so that you do not even need to reference it explicitly:
Code:
#!/bin/bash
while read aline; do
echo "$((++lcount)): ${aline}"
done
Hope that helps!
Last edited by astrogeek; 03-24-2022 at 07:50 PM.
Reason: Simplified C example, again
What is "not safe?" What harm does it do? Does it make my code run slower? Does it make my computer vulnerable to malware?
Daniel B. Martin
.
If you look again at the example I posted, you'll see I asked it to run one script, but it actually ran a completely different one. So, yes, potentially it's vulnerable to abuse, but the short answer is that it's just wrong.
You can move the free() and line=NULL outside the loop. getline() will reuse the buffer, calling realloc() only if it is not currently large enough to hold a subsequent line.
get the habit of using (may need to download) shellcheck to vet scripts
Code:
% cat bad.sh
#
#/bin/bash
echo "hello $(date)"
% shellcheck bad.sh
In bad.sh line 1:
#
^-- SC2148 (error): Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.
For more information:
https://www.shellcheck.net/wiki/SC2148 -- Tips depend on target shell and y...
Taking advice from astrogeek and constructive criticism from GazL, I offer this example in response to the OP's question.
Advice, corrections, improvements are welcome.
This script ...
Code:
#!/bin/bash
# Daniel B. Martin Mar22
# To execute this program, launch a terminal session and enter:
# bash /home/daniel/Desktop/LQfiles/dbm2324.bin
# This program inspired by ...
# https://www.linuxquestions.org/questions/programming-9/
# how-to-write-a-terminal-program-that-i-can-pipe-the-input-into-it-4175709904/
# This program solicits user input,
# sorts the words in each line alphabetically,
# displays each sorted line,
# and builds a file of all sorted lines.
# File identification
Path=${0%%.*}
OutFile=$Path"out.txt"
echo
echo 'This program solicits keyboard entry of text lines.'
echo 'The words in each line are reordered by an alphabetic sort.'
echo 'An output file is created which contains all the sorted lines.'
echo
rm -f $OutFile # Blow away a leftover file.
while : # This sets up an infinite loop.
do
echo; echo 'Please enter a line of text. A null line ends execution.'
read aline
if [ -z "$aline" ]; then break; fi # If null string, exit loop.
sline=$(tr ' ' '\n' <<< "$aline" \
|sort \
|tr '\n' ' ')
echo 'Before sorting: '$aline
echo 'After sorting: '$sline
echo $sline >>$OutFile # Append one sorted line to OutFile.
done
echo; echo 'This is the OutFile...'; cat $OutFile
echo; echo 'Normal end of job.'; exit
It produced this on-screen result...
Code:
This program solicits keyboard entry of text lines.
The words in each line are reordered by an alphabetic sort.
An output file is created which contains all the sorted lines.
Please enter a line of text. A null line ends execution.
mary had a little lamb
Before sorting: mary had a little lamb
After sorting: a had lamb little mary
Please enter a line of text. A null line ends execution.
its fleece was white as snow
Before sorting: its fleece was white as snow
After sorting: as fleece its snow was white
Please enter a line of text. A null line ends execution.
This is the OutFile...
a had lamb little mary
as fleece its snow was white
Normal end of job.
danielbmartin,
A bit off topic but I will try to give a quick answer about the shebang line.
bash myscript
In your example your using bash to run the script and since the shebang line starts with a # it is treated as a comment.
However if you run the script as a stand alone executable program, the shebang line is passed to the interpreter basically like a command. Anything after the command i.e /bin/bash is treated like an option.
#!/usr/bin/env python3
In the above shebang example runs env which searches and runs the python3
Actually shebang i.e #! is a magic number.
It could lead to some catastrophic event if your comment is interpreted as real command like rm...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.