Visit Our UNIX and Linux User Community


Issue with writing a pipe


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Issue with writing a pipe
# 1  
Old 03-12-2020
Issue with writing a pipe

Heyas

I dont get why I only get the first item of multiple passed strings.

Code:
	printe() { # STR1 STR2 STR3
	# Simply prints the strings as passed
	# It requires 3 strings to use the center
		case "$1" in
		"--"|"-")
				# Read pipe, expect one line
				read LEFT CENTER RIGHT
				set "$LEFT" "$CENTER" "$RIGHT"
				echo " --------------"
				echo "$LEFT $CENTER $RIGHT :: ${@}"
				;;
		esac
	}
	${ECHO:-\echo} This is piped | printe -

Output I get:
Code:
 --------------
This   :: This

Output I expected:
Code:
This is piped :: This is piped

Though, 'everything' after the :: is just from my 'verification', and that failed, which increased my confusion.

Any ideas or suggestions?
Thank you


EDIT -----------------------------

Errr... ok I need to rephrase this.... hold on

Just figured, it'll work just fine with echo!
But, I have to use printf because there are systems not having echo - at least that's what my memory tells me from when I last tested these things.

I'll try to figure it out now, but if you would happend to have a solution at hand, I'd be happy to read it Smilie

tia

--- Post updated at 03:53 ---

LOL ok, was a simple thing...
Just regular syntax fixed it Smilie

/solved

But, what EXACTLY does printf %q str do?
Helps says: That it can be reused as shell input..
I dont get it - because I can also use %s with the same result (in my situational case here right now).

Does that just mean that, probable codes would be preserved?

Last edited by sea; 03-12-2020 at 10:39 PM..
# 2  
Old 03-13-2020
Hi Sea,

The behaviour of printf and echo are different.

Code:
$ echo This is piped
This is piped

and
Code:
$ echo "This is piped"
This is piped

produce the same output*, but this is not the case for printf
Code:
$ printf "%s\n" This is piped 
This
is
piped

Code:
$ printf "%s\n" "This is piped" 
This is piped

This is why you got the output, since unquoted it produces multiple lines and
read LEFT CENTER RIGHT only reads the first line..


--
* In the first case there are 3 arguments, in the second case there is only one.

--
"%q" is likely not portable.
Also I don't expect it to work as intended, try putting quotes around the output of the variables:
Code:
echo "\"$LEFT\" \"$CENTER\" \"$RIGHT\" :: \"${@}\""

Then printf "%q\n" "This is piped" | printe - produces:
Code:
"This is piped" "" "" :: "This is piped  "


Last edited by Scrutinizer; 03-13-2020 at 02:57 AM..
# 3  
Old 03-13-2020
Use an echo_ function
and set ECHO=echo_!
This User Gave Thanks to MadeInGermany For This Post:
# 4  
Old 03-13-2020
Well, what I want to achieve, well.. keep... is this:

Please understand that I'd like to replace the used echo with printf.
Code:
echo "this is piped" | print -
# | This is piped                                           | #

And
Code:
echo  this is piped | -
# | this                     is                       piped | #

Should be the same as:
Code:
echo "this is" "a piped" "test code"| printe -
# | this is               a piped             test code | #

Again, TUI was refering to echo, which is the reason it worked before.
With SWARM, I'd like to keep using 'printf' as internal core output, as I'm still under the impression that NOT ALL *nix flavors provide an actual echo command.

What I currently have is this:
Code:
	echo " ----------- TEST AREA -----------"
	## Core sanity
	# swarm.sanity.env
	header 	"SWARM ${SWARM[VERSION]}" " " "$DATE_TODAY : $DATE_TIME"
	title 	"my title"
	printe 	left middle right

	printf '%q ' 1This is piped | printe -
	printf '%q ' "2This is" "a piped" "test code" | printe -
	printf '%s\n' "3This is" "a piped" "test code" | printe -
	#ask "Is this cool?"
	echo $?
	#echo "$(swarm.help VERSION)"
#set +x
	echo " ----------- TEST AREA -----------"

Which outputs to:
Code:
 ----------- TEST AREA -----------
# | SWARM 0.3                                                                                  2020.03.13 : 15:16 | #
# |                                                   my title                                                    | #
# | left                                               middle                                               right | #
# | 1This                                                is                                                 piped | #
# | 2This is                                           a piped                                          test code | #
# | 3This                                                is                                                       | #
0
 ----------- TEST AREA -----------

So only the line where the text starts with 2 seems to be working as expected, or at least, as intended.
This said, true that, for multiple lines I'd need special handling- which I think worked 'out of the box' when I had used echo...

Now you tell me to use an 'echo' function, whereas in the feedback thread the commone-tone was to NOT use functions that are labeld as regular commands, such as specificly named 'echo'.
Regardless, if no echo exists, I could 'load' a function named echo, but that still doesnt make the use of printf in that echo-function work as I hoped it would.

On the other hand, if someone could correct me and tell me i'm wrong and therefor:
That echo exists on ALL *nix flavored systems - and not just 'on most'.

We'd all save time and headaches.
Specialy the multi-line piping would work right away...

This said, I'd rather try to write/set an $ECHO variable

OOOrr.... I'd simply remove the 3 orientations from the piping, and pretty sure this would help with multi-line pipes.
But thats like the easy way.

Strangley enough, the following produced borked output lines...
shift was required, as the first two lines had only '-' as their output, now, follow up lines miss the first entry, allthough all passed values started with the pipe indicator.. Smilie
Code:
	printe() { # STR1 STR2 STR3
	# Simply prints the strings as passed, end with newline
	# It requires 3 strings to use the center
		case "$1" in
		"--"|"-")
				# Read pipe, expect one line
				shift 
				while read LEFT CENTER RIGHT
				do
					set "${LEFT}" "$CENTER" "$RIGHT"
					printe "$LEFT" "$CENTER" "$RIGTH"
				done
				;;
		esac
		swarm.print.border -e
		swarm.print.text -e "$1" "$2" "$3"
		$PRINTF "$posEND\n"
	}

While this enables multi-line pipeing (from grep, cat, etc), it causes an error messages at some math point I need to find first, also no idea where this 'fg %s' comes from...
Code:
[sea@manjaro-desktop SWARM]$ time . ./runtime
........bash: fg: %s: no such job

TODO : swarm.sanity.env
.............bash: [[: ''1'': syntax error: operand expected (error token is "''1''")

 ----------- TEST AREA -----------

Well, the echo function didnt quite work as expected:
Code:
	echo() { printf '%q ' "${@}";}
	ECHO=echo_!

Code:
bash: echo_!: command not found
bash: echo_!: command not found
bash: echo_!: command not found

Any thoughts please?
Thank you

--- Post updated at 19:11 ---

No I mean, seriously... Im confused..

Which is true now?

Code:
[sea@manjaro-desktop SWARM]$ unset echo
[sea@manjaro-desktop SWARM]$ which echo
/usr/bin/echo
[sea@manjaro-desktop SWARM]$ type echo
echo is a shell builtin

Might this be the riddles solution?
Code:
[sea@manjaro-desktop SWARM]$ LC_ALL=C $(which echo) --help | grep -a3 NOTE
  \0NNN   byte with octal value NNN (1 to 3 digits)
  \xHH    byte with hexadecimal value HH (1 to 2 digits)

NOTE: your shell may have its own version of echo, which usually supersedes
the version described here.  Please refer to your shell's documentation
for details about the options it supports.

Does that mean all BASH version have their own builtin echo?
But not all *nix flavors have a 'physical' echo-binary?

In which case, all of this threads would really be solved. Smilie

Sometimes you see things you havent all the times before....
# 5  
Old 03-13-2020
Ok did some more research.

While this confirms my confusion (missing better words here..), I learned some new things allthough most of it was known.
Asdide the fact that 'echo' is both, for some reason I always thought that /bin/echo was the echo used when calling echo, and thus not realized the builtin existed - or that they are different 'code'.
How to distinguish between builtin and external util? (e.g. echo) - Unix & Linux Stack Exchange


This one here seems to confirm my most recent assumptions as since today:
shell - Which are the standard commands available in every Linux based distribution? - Unix & Linux Stack Exchange

That I most likley could rely on the bash builtin 'echo' for the use of SWARM.
But none of that sounded certain, so I then I followed a link of the 2nd post (46 up votes) about the standarized commands by PSIX and ended up here: echo

Now, when you go down to the 'Application Usage' section, you'll see this part:
Code:
It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted.

The printf utility can be used portably to emulate any of the traditional behaviors of the echo utility as follows (assuming that IFS has its standard value or is unset):

The historic System V echo and the requirements on XSI implementations in this volume of POSIX.1-2017 are equivalent to:

printf "%b\n" "$*"

The BSD echo is equivalent to:

if [ "X$1" = "X-n" ]
then
    shift
    printf "%s" "$*"
else
    printf "%s\n" "$*"
fi

New applications are encouraged to use printf instead of echo.

Now my final question, which of these 2 examples would you recomend?
I have to ask this, because I lack the practical experience of actual daily usage on different systems.

Anyway, I'm going to try this out now.
Lets see which works better as expected.

At least I know now that it wasnt a waste of time preparing $ECHO to use printf, what a relieve! Smilie
# 6  
Old 03-13-2020
Did you really read my post?
I wanted to tell you this:
Code:
# Simple echo
echo_(){
  ( IFS=" "; printf "%s\n" "$*" )
}

ECHO=echo_

The function is named echo_ (not echo and not echo_!)
and has %s (not %q)
and has IFS and has a subshell.

It works like a plain echo but without taking any options (that are not portable):
Code:
echo_ test 1 2
test 1 2
echo_ "test 1 2"
test 1 2
echo_ -n is a -n
-n is a -n
echo_ "-n is a -n"
-n is a -n

# 7  
Old 03-13-2020
Oh boy, I'm sorry, just seen the link to MIG's echo...
Awesome, thank you!

I'm currently thinking about a 'catch' function for the type and which cases, and how to implement his solutions as a fallback.
Might even start with a locate and find if which should not be available - for 'general usage' -> for the swarm.sanity.env section Smilie

On the other hand....
Using his solution all along would help to ensure (a further step) same results all the way, regardless of whats on the system available.

Which would be a great thing, if it would work as I hoped Smilie
Code:
	echo_	"This is" 	"another piped" 	"test run" | printe -
	echo_e	"This is" 	"another piped" 	"test run" | printe -
	echo_n	"This is" 	"another piped" 	"test run" | printe -
	echo_en	"This is" 	"another piped" 	"test run" | printe -
	echo_q	"This is" 	"another piped" 	"test run" | printe -
	printf '%q ' "This is" 	"another piped" 	"test run" | printe -
	type echo_q

Outputs as:
Code:
# | This                                                 is                                another piped test run | #
# | This                                                 is                                another piped test run | #
# | This                                                 is                                another piped test run | #
# | This                                                 is                                another piped test run | #
# | This                                                 is                                another piped test run | #
# | This is                                         another piped                                        test run | #
echo_q ist eine Funktion.
echo_q () 
{ 
    printf '%q ' $*
}

But it should be like,
Code:
# | This is                                another piped                                                 test run | #

which only the 'hardcoded' printf '%q ' "str1" "str2" "str3" achieves.

Based on that, I tried this - to "partial" success...
Code:
echo_q () 
{ 
    printf '%q ' "$1" "$2" "$3"
}
# | testoutput                                           ''                                                    '' | #

Because of course I dislike the 2x2 single quotes...

All this isnt worth it - i give up on this, I guess I'll just do left orientations on pipes... saves alot of trouble, and that at least, I can achieve constistantly.

EDIT:
@ RudiC, yes, as of this post I've figured the link - before (so, in the previous posts) I just blindly did something.

EDIT2:
I mean... SWARM is for FREAKING END USER VISUALS...
"You" as a script author are supposed to make that certain... with piping some output, you cant promise a good interface to your enduser anyway (not with a 3 orientation output that is, obviously!!).

Also stuff like echo y | ask "question" is just stupid (in 'this' context) and has no practical use in/for SWARM...
Once you've used 'swarm' to browse within folders and execute stuff.. you'll understand why -> because writing that 'echo y n 1 3 15 n | <swarm based script cmdline>' takes as long as use those args upon the actual call... because if properly coded, you'd get the same result using the args that script should provide, without the need to pipe.

Granted, this is my bias based on the image/result I have in mind.

So again, I fell for standards - that really dont apply... GNARGH

I'm sorry, but i feel like that left, center and right for separate string orientation (read: "Work with 3 individual strings per line") is TOO MUCH for the current existing GNU/POSIX standards.
These are the kind of issues that caused my last "burnout".

--- Post updated at 23:17 ---

Lets just put this under:
* Would be nice to have

And MIG, just to assure you, I've copied your echo_* functions as-is from your thread.
What I've 'quoted' was just additional trial adjustments. (for the pipes, still helpfull for general fallback usage! So again, thank you for those!)

/solved /resigned

Last edited by sea; 03-13-2020 at 06:34 PM..

Previous Thread | Next Thread
Test Your Knowledge in Computers #724
Difficulty: Medium
The Plan 9 operating system was the first machine to achieve a Master rating in chess.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

While read pipe input issue

Hello, I have an ffmpeg bash script which is working nice and I need to do the same for other sources. To create new scripts and to deal with multiple bash files sounds not logical. It is a bit hard to manage for me.. I wondered if it was possible to make my input file as variable. Then I... (1 Reply)
Discussion started by: baris35
1 Replies

2. Shell Programming and Scripting

How to ignore Pipe in Pipe delimited file?

Hi guys, I need to know how i can ignore Pipe '|' if Pipe is coming as a column in Pipe delimited file for eg: file 1: xx|yy|"xyz|zzz"|zzz|12... using below awk command awk 'BEGIN {FS=OFS="|" } print $3 i would get xyz But i want as : xyz|zzz to consider as whole column... (13 Replies)
Discussion started by: rohit_shinez
13 Replies

3. Shell Programming and Scripting

Variable value substitution issue with awk command issue

Hi All, I am using the below script which has awk command, but it is not returing the expected result. can some pls help me to correct the command. The below script sample.ksh should give the result if the value of last 4 digits in the variable NM matches with the variable value DAT. The... (7 Replies)
Discussion started by: G.K.K
7 Replies

4. Shell Programming and Scripting

Need assistance with a file issue and a terminal issue

Hello everyone, I'm in need of some assistance. I'm currently enrolled in an introductory UNIX shell programming course and, well halfway through the semester, we are receiving our first actual assignment. I've somewhat realized now that I've fallen behind, and I'm working to get caught up, but for... (1 Reply)
Discussion started by: MrMagoo22
1 Replies

5. UNIX for Dummies Questions & Answers

grep pipe filename print issue

uname -a SunOS mypc 5.10 Generic_141414-07 sun4v sparc SUNW,SPARC-Enterprise-T2000 uname -a SunOS mypc 5.10 Generic_144488-07 sun4v sparc SUNW,SPARC-Enterprise-T5220 find . -name "*.cer" -exec keytool -v -list -printcert -file {} \; | grep -i "Aug 03" Valid from: Mon Jan 29 00:00:00 GMT... (16 Replies)
Discussion started by: shifahim
16 Replies

6. Shell Programming and Scripting

Replace pipe with Broken Pipe

Hi All , Is there any way to replace the pipe ( | ) with the broken pipe (0xA6) in unix (1 Reply)
Discussion started by: saj
1 Replies

7. Shell Programming and Scripting

How can I use pipe

Hi, guys: I am working on my shell using c. How can I use pipe to implement the following? ls -l 1>> | grep hellp 1<< 2>> | less 2<< (the output of ls goes to grep, and the output of grep goes to less) Thanks Please use and tags when posting code, data or logs etc. to preserve... (1 Reply)
Discussion started by: tomlee
1 Replies

8. Programming

writing a pipe with a c telnet

Hi I have a problem writing a c program that makes a telnet connection and writes some command. The shell command is something like this: ------------------------------------------------------------------ > >telnet 141.111.231.132 3300 ENTER COMMAND: login "<--- I' wirte a command (ex... (5 Replies)
Discussion started by: fafo77
5 Replies

9. Shell Programming and Scripting

Unix Arithmatic operation issue , datatype issue

Hi, I have a shell scripting. This will take 7 digit number in each line and add 7 digit number with next subsequent lines ( normal addition ). Eg: 0000001 0000220 0001235 0000022 0000023 ........... ......... ........ Like this i am having around 1500000 records. After adding... (23 Replies)
Discussion started by: thambi
23 Replies

10. Programming

pipe help

i made a lot of processes. here is the code: main() { printf("\nEnter K="); scanf("%d",&k); printf("Enter L="); scanf("%d",&l); printf("\nFather id=%d\n",getpid()); x=0; makechild(); sleep(2); return 1; } int makechild() { for(q=1;q<=k;q++) { if(f=fork()) { ... (5 Replies)
Discussion started by: bb666
5 Replies

Featured Tech Videos