Diese Website existiert nur weil wir Werbung mit AdSense ausliefern.
Bitte den AdBlocker daher auf dieser Website ausschalten! Danke.

[solv] herausfinden, ob ein Skript per Pipe aufgerufen wurde

Alles rund um die verschiedenen Konsolen und shells sowie die Programmierung unter Linux

Moderator: Moderatoren

Antworten
Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

[solv] herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von OsunSeyi » 21. Mai 2015, 19:21

Hi
Denkbar wäre

Code: Alles auswählen

VALUES=`cat -`
Wenn $VALUES dann leer ist, weil keine Werte per Pipe übergeben wurde, soll statt dessen die Zwischenablage ausgelesen werden (VALUES=`xsel -p`).

Das Problem ist aber, daß das Script bei "cat -" quasi stehen bleibt, wenn es nicht per Pipe aufgerufen wurde.
Das Script müsste also "merken", ob es über eine Pipe oder ganz normal aufgerufen wird!

Code: Alles auswählen

> echo '123' | script
   oder:
> script
Ich hoffe, mich verständlich ausgedrückt zu haben...
Ist das irgendwie zu realisieren?

viele Grüße
tom
Zuletzt geändert von OsunSeyi am 29. Mai 2015, 22:58, insgesamt 1-mal geändert.

Werbung:
Benutzeravatar
robi
Moderator
Moderator
Beiträge: 3167
Registriert: 25. Aug 2004, 02:13

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von robi » 21. Mai 2015, 23:04

Bei Einzelwörtern/Einzelwerten/.....usw geht sowas zB über einen Timeout bei read.

Code: Alles auswählen

#!/bin/bash
read -t1 DATA
if [ -z $DATA ] ; then DATA=$(xsel -p) ;fi
echo $DATA
# echo testparameter | ./script.sh
testparameter
# ./script.sh
Ich komme aus der X-Zwischenablage
#
Wenn du mehrere mit Leerzeichen, Tabulator oder Zeilensprung getrennte Dinge auf diese Weise im Script verarbeiten willst, musste man das recht kompliziert und wohl sehr individuell ausfeilen. Da die Eingaben aus xsel dann wohl auch noch überprüft werden müssten, ob das überhaupt irgendwas Sinnvolles sein könnte was das Script verarbeiten kann ......

robi

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von OsunSeyi » 21. Mai 2015, 23:47

Vielen Dank, das ist genau das gesuchte!
Im Fall "cat file | skript" kann das als Test verwendet werden, ob das Skript via Pipe aufgerufen wurde oder nicht.
:)

Code: Alles auswählen

#	Teste auf Werteübergabe per Pipe:
	read -t 0.1 TEST
	if [ -z "$TEST" ] ; then

		VAL=`	xsel -p						|\
			awk 'BEGIN { FS = "\t" }
				   { print $'$COLUMN'  }'`

		NUM=`echo $VAL | sed 's| \+|+|g' | sed 's|+-|-|g'`

	else
		VAL=`	awk 'BEGIN { FS = "\t" }
				   { print $'$COLUMN'  }'`

		NUM=`echo $VAL | sed 's| \+|+|g' | sed 's|+-|-|g'`
	fi
echo 'scale=2; '$NUM | bc
Zum Berechnen von Zahlenwerten in einer vorgegebenen Spalte entweder einer ganzen Datei (echo file | skript) oder nur eines markierten Teilbereiches (skript). Das Ganze ist natürlich länger, und man könnte es sicher auch anders realisieren. Aber so ist es für mich am leichtesten zu merken...

}-Tux-{
Hacker
Hacker
Beiträge: 698
Registriert: 12. Dez 2004, 19:54
Kontaktdaten:

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von }-Tux-{ » 22. Mai 2015, 23:24

Alternative zum read: tty bzw. tty -s und dann den Return-Code checken.


}-Tux-{

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von OsunSeyi » 23. Mai 2015, 17:43

Der zweite Weg (tty prüfen) ist bei 'gepipten' Dateien, die mit einer Leerzeile beginnen, anscheinend der funktionierendere Weg.
Auch 'egrep [[:graph:]] | read TEST' bringt seltsamerweise eine leere Variable!

abgdf
Guru
Guru
Beiträge: 3188
Registriert: 13. Apr 2004, 21:15

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von abgdf » 23. Mai 2015, 19:14

Immer machst Du so komische Sachen. ;) Ich bin ziemlich sicher, daß Du das, was Du eigentlich erreichen willst, auch eleganter hinbekommen könntest, ohne zu prüfen, ob da eine Pipe im Spiel war oder nicht.

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von OsunSeyi » 23. Mai 2015, 19:34

Das ist zum Ausrechnen von Spalten in Abrechnungsdateien und kann auf alle möglichen Arten eingesetzt werden.
Da sind zB zwei Zeilen markiert, und 'summe -1' rechnet die erste Spalte.

'cat 0-Gelder | summe -1' rechnet die ganze Datei.

Natürlich geht das auch anders (vie zB Option -c wie Clipboard), aber so ist es total simpel.
Einfach etwas markieren und 'summe' eingeben, klappt meistens auch.
Dann wir alles, was nicht [[:summe:]]+(\.[[:summe:]]{2})? ist, und in einer eigenen Spalte steht, entfernt.
Das würde obiges auch rechnen, und ist unübertroffen simpel.

Bild

abgdf
Guru
Guru
Beiträge: 3188
Registriert: 13. Apr 2004, 21:15

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von abgdf » 24. Mai 2015, 00:38

Ok, dieses "summe" ist aber ein sehr exotischer Befehl (oder ein selbstgeschriebenes C-Programm?). Nicht mal die Google-Suche nach Teilen der man-page wie "Gut fuer Gimp-Stundenzettel" findet was.
Zum Addieren von Spalten in einer Datei gibt es awk, das ist primär dafür gemacht.
(Ich persönlich schreibe mir dafür schnell ein Skript in Perl oder Python, weil ich das besser kann.)
Wie ich schon dachte, ist das Prüfen auf Pipe dafür nicht erforderlich.

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von OsunSeyi » 25. Mai 2015, 13:20

Wofür denn die Frage ;)

Code: Alles auswählen

#!/bin/sh
## summe [-t] [-2] [-v]
##
##	addiert alle Zahlen aus dem Clipboard, der Standardeingabe (Pipe) oder aus "$*",
##	je nach Zweck. Gut fuer Gimp-Stundenzettel oder um Spalten zu rechnen.
##
#										01.09.2012
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
										     . inc
	  TMP0=$SRC/tmp/summe0.tmp
	  TMP1=$SRC/tmp/summe1.tmp

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##	[-v]     zeigt die Rechnung (verbal).
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	VERBAL=`echo $* | grep  '\-v'`

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##	[-t]     hilft, Zeiten im Stundenzettel zusammenzurechnen.
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	 TIMES=`echo $* | grep  '\-t'`

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##	[-2]     gibt die zu rechnende Spalte an (Trenner ist Tab).
##		 das geht via Pipe oder aus der fluechtigen Zwischenablage.
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	COLUMN=`echo $* | sed 's|-v||g' | egrep  '^ *-[[:digit:]]+ *$' | sed 's|^.*-\([[:digit:]]\+\).*$|\1|g'`

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##	[1 2 -3] wird einfach addiert.
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	VALUES=`echo $* | sed 's|-[A-Za-z]\+||g'`

##	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##	ohne Option ("verbal" ausgenommen) wird aus der fluechtigen Zwischenablage
##	gelesen, Text wird vorher entfernt.
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	if [ -z "$VALUES" -a -z "$TIMES" -a -z "$COLUMN" ] ; then VALUES=`xsel -p` ; fi

#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#/////  S P A L T E N   A D D I E R E N  /////////////////////////////////////////////////
#=========================================================================================

  if [ -n "$COLUMN" ] ; then

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	Teste auf Werteübergabe per Pipe.
#	Das geht nach langem Suchen auf diese Weise, siehe:
#	http://forum.linux-club.de/viewtopic.php?f=91&t=120294
#	Alternative zum read: tty bzw. tty -s und dann den Return-Code checken
#	read -t 0.1 TEST (geht nicht, wenn die Datei mit einer Leerzeile beginnt)
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	TEST=`tty | grep 'not a tty'`

	if [ -n "$TEST" ] ; then

#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#		Wurde etwas per Pipe übergeben:
#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		VAL=`	awk 'BEGIN { FS = "\t" }
				   { print $'$COLUMN'  }'				|\
											 \
			egrep '^ *-?[[:digit:]]+(\.[[:digit:]]{2})?$'`

		NUM=`	echo $VAL | sed 's| \+|+|g' | sed 's|+-|-|g'`
	else
#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#		Wurde nicht etwas per Pipe übergeben, probiere die Zwischenablage:
#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		VAL=`	xsel -p								|\
											 \
			awk 'BEGIN { FS = "\t" }
				   { print $'$COLUMN'  }'				|\
											 \
			egrep '^ *-?[[:digit:]]+(\.[[:digit:]]{2})?$'`

		NUM=`	echo $VAL | sed 's| \+|+|g' | sed 's|+-|-|g'`
	fi
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	Rechnung und Ergebnis ausgeben:
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	ERG=`echo 'scale=2; '$NUM | bc`

	if [ -n "$VERBAL" ] ; then echo -n ' '$NUM' =' ; fi

	echo -e $hellrot $ERG $def 
	echo    $ERG | xsel -b -i

	exit 0
  fi
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#/////  S T U N D E N Z E T T E L :   Z E I T E N   A D D I E R E N  /////////////////////
#=========================================================================================

  if [ -n "$TIMES" ] ; then

	xsel -p    > $TMP0
	echo -n '' > $TMP1

	line=0						# aktuelle Zeile
	lines=`wc -l $TMP0 | sed 's| .*$||g'`		# Anzahl der Zeilen

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	Damit auch Leerzeilen berücksichtigt werden, jede Zeile einzeln:
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	while [ $line -le $lines ] ; do

		line=`expr $line + 1`			# hochzählen
		 row=`sed -n $line'p' $TMP0`		# Zeile auslesen

#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#		Zeilen mit Zeitangaben
#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		if [ -n "$row" ] ; then

#			~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#			Eine Zeitangabe ist z.B. "7.45 10.30":
#
#			Ersetze viertel, halbe, dreiviertel Stunden nach dezimal
#			Vertausche die beiden Zeiten (um abziehen zu können),
#			und füge ein '-' ein.
#
#			"$NUM" ist der String, mit dem 'bc' rechnen wird.
#			~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			NUM=`echo $row | sed 's|\.15|.25|g' | sed 's|\.30|.5|g' | sed 's|\.45|.75|g'	|\
													\
			     sed 's|^\([^ ]\+\) \(.*\)$|\2-\1|g'`

#			Ergebnis rechnen, formatieren und ausgeben:

			echo 'scale=2; '$NUM | bc 							|\
													 \
			sed 's|0\+$||g' | sed 's|^\.|0.|g' | sed 's|\.$||g' | tr '.' ','		 \
													 \
			>> $TMP1

#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#		Leerzeilen
#		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		else
			echo $row >> $TMP1
		fi
	done

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	Das Ergebnis kommt in die echte Zwischenablage ("clipboard")
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			cat $TMP1 | xsel -b -i
			echo 'Ergebnis ist im Clipboard'
	exit 0
  fi

#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#/////  Z A H L E N   A D D I E R E N  ///////////////////////////////////////////////////
#=========================================================================================

  if [ -n "$VALUES" ] ; then

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	Anspruch ist, das ganze Blöcke incl. Labels und Daten (11.11.11) gerechnet werden.
#	Folgende Ersetzungen werden vorgenommen:
#
#			Zeilenumbrüche entfernen
#			alles, was mehrere Punkte hat (z.B. Daten), entfernen
#			Komma zu Punkt
#			alles, was keine Ziffer und kein und kein Minus Punkt ist, zu Leerzeichen
#			String trimmen
#			Leerzeichen zwischen den Zahlen zu je einem "+"
#			"+" und "-" = "-" für negative Zahlen, weil Minuszeichen auch an
#			anderer Stelle (in Texten) vorkommen können, mehrfache entfernen
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	NUM=`echo $VALUES 							|\
										 \
			tr '\n' ' '						|\
			sed 's|[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+||g'  |\
			tr ',' '.'						|\
			sed 's|[^-.[:digit:]]| |g'				|\
			sed 's|^[[:space:]]*||g'				|\
			sed 's|[[:space:]]*$||g'				|\
			sed 's|[[:space:]]\+|+|g'				|\
			sed 's|+-|-|g' | sed 's|--\+|-|g'`

#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	Rechnung und Ergebnis ausgeben:
#	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	ERG=`echo 'scale=2; '$NUM | bc`

	if [ -n "$VERBAL" ] ; then echo -n ' '$NUM' =' ; fi

	echo -e $hellrot $ERG $def 
	echo    $ERG | xsel -b -i

	exit 0
  fi

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@FIN@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Wie ich schon dachte, ist das Prüfen auf Pipe dafür nicht erforderlich.
Nein, natürlich nicht.
So gesehen.
Aber einfacher, wenn das Skript selber entscheidet und ich keine Option extra bemühen muss.
Ist doch nur für meinen Eigenbedarf.
Ausser dem ist das Thema als solches doch eine Frage wert??

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von OsunSeyi » 29. Mai 2015, 22:55

Übrigens ist es doch bei vielen Programmen absolut normal:
Wie etwa "grep file" oder "cat file | grep".

abgdf
Guru
Guru
Beiträge: 3188
Registriert: 13. Apr 2004, 21:15

Re: herausfinden, ob ein Skript per Pipe aufgerufen wurde

Beitrag von abgdf » 29. Mai 2015, 23:07

OsunSeyi hat geschrieben:Übrigens ist es doch bei vielen Programmen absolut normal:
Wie etwa "grep file" oder "cat file | grep".
Ich hab' jetzt nicht den Source-Code von grep angesehen, aber ich vermute, daß grep seine Optionen durchgeht, und wenn die Syntax des Aufrufs darauf hindeutet, daß kein Dateiname mitgegeben wurde, davon ausgeht, daß es von STDIN lesen soll. Ich glaube nicht, daß es den Unterschied ernsthaft prüft.

Im übrigen ist Deine zweite Variante ein "Useless use of cat".
So, jetzt bist Du wahrscheinlich sauer, aber ich mein's nicht böse. :D

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 373
Registriert: 27. Mai 2006, 01:28

Re: [solv] herausfinden, ob ein Skript per Pipe aufgerufen w

Beitrag von OsunSeyi » 29. Mai 2015, 23:46

Ist ja nur ein Beispiel, kein Problem...
Diese lesenswerte deutschsprachige Seite bei Ubuntu gibt jede Menge Beispiele, die sich auch in meinen Skripten wiederfinden. Du hast also vollkommen Recht. Irgendwie nagel ich immer alles zusammen, Hauptsache es hält...
:-)

Antworten