Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bc: Umbruch und Eingabe

4 views
Skip to first unread message

Marcel Logen

unread,
Apr 10, 2023, 5:02:32 AM4/10/23
to
Derzeit beschäftige ich mich mit ganzen Zahlen modulo 2^255-19,
siehe [1].

[1] Subject: ignore 04494.08 - Curve25519
Newsgroups: de.test
From: Marcel Logen <33320000...@ybtra.de>
Date: Thu, 30 Mar 2023 02:31:25 +0200
Message-ID: <AABkJNhdF3sAA...@t20.ybtra.de>
<news:AABkJNhdF3sAA...@t20.ybtra.de>

Dafür benutze ich das Tool "bc" - in den Varianten "OpenBSD-bc"
und "GNU-bc", siehe [2][3][4].

[2] <https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html>
[3] <https://man.openbsd.org/bc>
[4] <https://www.gnu.org/software/bc/manual/html_mono/bc.html>

Meine Fragen dazu:

1. Umbruch langer Zahlen

Große Zahlen im Output werden nach 70 Ziffern umbrochen, z. B. so:

| user15@o15:~/ybtra-o15$ bc -q
| 2^255-19
| 57896044618658097711785492504343953926634992332820282019728792003956\
| 564819949

Das finde ich meistens unpraktisch, vor allem, wenn ich Ergebnisse
herauskopieren und weiterverwenden möchte.

Laut POSIX-Manual hängt der Umbruch von der locale ab, aber ich
weiß nicht, bei welcher locale eben *kein* Umruch erfolgt.

Deshalb behelfe ich mir im nicht-interaktiven Modus so:

| user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
| 57896044618658097711785492504343953926634992332820282019728792003956564819949

Geht das vielleicht auch eleganter?

Hier auf diesem Rechner benutze ich zur Zeit GNU-bc:

| user15@o15:~/ybtra-o15$ bc --version
| bc 1.07.1
| Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
| user15@o15:~/ybtra-o15$

2. Übergabe von Werten und expressions

Beim OpenBSD-bc kann man per Option "-e" expressions übergeben,
bevor ein Script-File abgearbeitet wird. Das ist AFAICS beim GNU-
bc nicht möglich: Dort wird STDIN erst nach Abarbeitung der Files
gelesen, so daß ich vor dem Ausführen von Scripts keine Variablen-
Werte auf der command line angeben kann. Es gibt allerdings die
extension "read()". Hier jedoch kann man nur 'reine' Zahlen, aber
keine expressions (Programm-Code) übergeben. Auch umständlich,
wenn ich z. B. die Zahl "2^255-19" einspeisen will.

Gibt es da für GNU-bc eine Lösung?

Marcel
--
╭────────────╮ ╭───────────────╮ ..60..╭────╮
╰──────────╮ │ ╰───────╮ ╭─╯ ╭───╮ ╭──╮ ..60..╰──╮ ╰─
╭─────╮ ╭─╮ ╭──╯ ╰─╮ ╭──────╯ ╰──╮ │ │ ╭─╯ │ ..61..╭─╯
──╯ ╰───╯ ╰─╯ ╰─╯ ..36..╰──╯ ╰─╯ ╰──────────╯

Ulli Horlacher

unread,
Apr 10, 2023, 5:09:44 AM4/10/23
to
Marcel Logen <33320000...@ybtra.de> wrote:

> Deshalb behelfe ich mir im nicht-interaktiven Modus so:
>
> | user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
> | 57896044618658097711785492504343953926634992332820282019728792003956564819949
>
> Geht das vielleicht auch eleganter?

framstag@juhu:~: perl -Mbigint -wle 'print 2**255-19'
57896044618658097711785492504343953926634992332820282019728792003956564819949


--
Ullrich Horlacher Server und Virtualisierung
Rechenzentrum TIK
Universitaet Stuttgart E-Mail: horl...@tik.uni-stuttgart.de
Allmandring 30a Tel: ++49-711-68565868
70569 Stuttgart (Germany) WWW: https://www.tik.uni-stuttgart.de/

Helmut Waitzmann

unread,
Apr 10, 2023, 7:17:27 AM4/10/23
to
Marcel Logen <33320000...@ybtra.de>:

> Dafür benutze ich das Tool "bc" - in den Varianten "OpenBSD-bc"
> und "GNU-bc", siehe [2][3][4].
>
> [2] <https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html>
> [3] <https://man.openbsd.org/bc>
> [4] <https://www.gnu.org/software/bc/manual/html_mono/bc.html>
>
> Meine Fragen dazu:
>
> 1. Umbruch langer Zahlen
>
>
> Große Zahlen im Output werden nach 70 Ziffern umbrochen, z. B. so:
>
>
> | user15@o15:~/ybtra-o15$ bc -q
> | 2^255-19
> | 57896044618658097711785492504343953926634992332820282019728792003956\
> | 564819949
>
> Das finde ich meistens unpraktisch, vor allem, wenn ich Ergebnisse
> herauskopieren und weiterverwenden möchte.
>
> Laut POSIX-Manual hängt der Umbruch von der locale ab, aber ich
> weiß nicht, bei welcher locale eben *kein* Umruch erfolgt.
>
> Deshalb behelfe ich mir im nicht-interaktiven Modus so:
>
> | user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
> | 57896044618658097711785492504343953926634992332820282019728792003956564819949
>
> Geht das vielleicht auch eleganter?
>

Ich habe dazu das folgende Shell‐Skript «my_unfolded_bc» im PATH:


#!/bin/sh
bc "$@" | sed -e ': start; /\\$/ { N;s/\\\n//;b start;}'

Bei GNU‐bc geht es einfacher:  Es reicht laut Handbuch, die
Umgebungsvariable «BC_LINE_LENGTH» mit dem Wert «0» zu belegen,
um das Umbrechen abzuschalten.  Das könnte man mit dem
Shell‐Skript

#!/bin/sh
BC_LINE_LENGTH=0 bc "$@"

erledigen.

Marcel Logen

unread,
Apr 10, 2023, 10:07:55 AM4/10/23
to
Ulli Horlacher in de.comp.os.unix.apps.misc:

>Marcel Logen <33320000...@ybtra.de> wrote:

>> Deshalb behelfe ich mir im nicht-interaktiven Modus so:
>>
>> | user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
>> | 57896044618658097711785492504343953926634992332820282019728792003956564819949
>>
>> Geht das vielleicht auch eleganter?
>
>framstag@juhu:~: perl -Mbigint -wle 'print 2**255-19'
>57896044618658097711785492504343953926634992332820282019728792003956564819949

Interessant, danke.

| user15@o15:/tmp$ perl -wle 'print 2**255-19'
| 5.78960446186581e+76
| user15@o15:/tmp$ perl -Mbigint -wle 'print 2**255-19'
| 57896044618658097711785492504343953926634992332820282019728792003956564819949
| user15@o15:/tmp$ man bc

Da müßte ich dann aber alles auf Perl umstellen, was
ich eigentlich nicht vorhabe.

Das Beispiel war wohl eher flacsh gewählt von mir, denn
ich habe hier auch ein paar bc-Scripts, die mehrere Zei-
len ausgeben. Auf die soll das 'Entfalten' nämlich auch
anwendbar sein.

Marcel
--
╭────╮ ╭──╮ ╭──╮ ╭──╮ ..48..╭─╮ ╭──╮ ╭─╮
╭──╮ │ ╭─╯ ╭─╯ │ ╭────╮ ╭───╯ ╰───╯ ╰──╮ ╭──╯ ╰──╯ │ │ ╰─╮ ╭─
╭─╯ ╰─╯ ╰───╯ ╭─╯ ╰─╮ ╰─╯ ╰─╯ ..53..╭──╯ │ ╰─╯
──╯ ╰──────╯ ╰─────╯ ..67..

Marcel Logen

unread,
Apr 10, 2023, 10:14:35 AM4/10/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

>Marcel Logen <33320000...@ybtra.de>:

>>Große Zahlen im Output werden nach 70 Ziffern umbrochen, z. B. so:
[...]
>>Das finde ich meistens unpraktisch, vor allem, wenn ich Ergebnisse
>>herauskopieren und weiterverwenden möchte.
>>
>>Laut POSIX-Manual hängt der Umbruch von der locale ab, aber ich
>>weiß nicht, bei welcher locale eben *kein* Umruch erfolgt.
>>
>>Deshalb behelfe ich mir im nicht-interaktiven Modus so:
>>
>>| user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
>>| 57896044618658097711785492504343953926634992332820282019728792003956564819949
>>
>>Geht das vielleicht auch eleganter?
>
>Ich habe dazu das folgende Shell‐Skript «my_unfolded_bc» im PATH:
>
> #!/bin/sh
> bc "$@" | sed -e ': start; /\\$/ { N;s/\\\n//;b start;}'

Ah, verstehe. Mit "N" wird angehängt. Sehr geschickt!

>Bei GNU‐bc geht es einfacher:  Es reicht laut Handbuch, die
>Umgebungsvariable «BC_LINE_LENGTH» mit dem Wert «0» zu belegen, um das
>Umbrechen abzuschalten.

Das hatte ich doch glatt übersehen! Danke.

Im selben Abschnitt findet sich ja auch die Variable
"BC_ENV_ARGS", mit der ich mein zweites Problem evtl.
lösen kann. Ich schaue mir das mal an.

Marcel
--
╭─╮ ╭─╮ ╭──╮ ╭─────╮ ╭──────╮ ..67..
│ ╰──╯ │ │ ╰─────╯ ╭──╯ ╰──╮ ╰─╮ ..66..╭
╭─╯ ╭──╯ ..15..╰─╮ ╭──────╯ ╭──╮ ╰──╮ ╰─╮ ╭─╮ ╭────╮ │
╯ ╰───────────────╯ ╰──────────╯ ╰─────╯ ╰─────╯ ╰──╯ ╰────╯

Ulli Horlacher

unread,
Apr 10, 2023, 11:48:22 AM4/10/23
to
Marcel Logen <33320000...@ybtra.de> wrote:
> Ulli Horlacher in de.comp.os.unix.apps.misc:

>>> | user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
>>> | 57896044618658097711785492504343953926634992332820282019728792003956564819949
>>
>>framstag@juhu:~: perl -Mbigint -wle 'print 2**255-19'
>>57896044618658097711785492504343953926634992332820282019728792003956564819949
>
> Da müßte ich dann aber alles auf Perl umstellen, was
> ich eigentlich nicht vorhabe.

Wieso?
Du musst doch nur diese eine Zeile ersetzen.
Aber alles auf Perl umstellen ist sowieso eine gute Idee, das macht dein
Programm wesentlich robuster.
Fehlerbehandlung in sh-Skripten ist UHHAERXXX.



> Das Beispiel war wohl eher flacsh gewählt von mir, denn
> ich habe hier auch ein paar bc-Scripts, die mehrere Zei-
> len ausgeben. Auf die soll das 'Entfalten' nämlich auch
> anwendbar sein.

Die nach Perl zu transformieren duerfte trivial sein.

Marcel Logen

unread,
Apr 10, 2023, 12:43:22 PM4/10/23
to
Marcel Logen in de.comp.os.unix.apps.misc:

>Helmut Waitzmann in de.comp.os.unix.apps.misc:
>>Marcel Logen <33320000...@ybtra.de>:

>>>Große Zahlen im Output werden nach 70 Ziffern umbrochen, z. B. so:

Es sind natürlich nur 68, dann folgen Backslash und Newline.

[...]

>Im selben Abschnitt findet sich ja auch die Variable
>"BC_ENV_ARGS", mit der ich mein zweites Problem evtl.
>lösen kann. Ich schaue mir das mal an.

Scheint mir aber nicht zu helfen, denn

| This allows the user to set up "standard" options and
| files to be processed at every invocation of bc.

Ich benötige für jeden Aufruf andere Werte. Aber tatsäch-
lich *vor* der Abarbeitung des Scripts.

Ingrid
--
─╮ ╭──╮ ╭──────╮ ╭──────╮ ╭────╮ ╭──╮ ╭─╮ ..59..╭──╮
╰─╯ ╰──╯ ╭─╯ ╰──╮ │ ╰──╮ ╰─╮ ╭─╯ ╰────╯ ╰─╮ ╭──╯ ╰──╮
...7..╭─╯ ╭──╮ │ ╰─╮ ╭─╯ ╰─╯ ╭────────╯ │ ╭─────╯
╰────╯ ╰───╯ ╰────╯ ..43..╰────────────╯ ╰───────

Marcel Logen

unread,
Apr 10, 2023, 12:50:48 PM4/10/23
to
Ulli Horlacher in de.comp.os.unix.apps.misc:

>Marcel Logen <33320000...@ybtra.de> wrote:
>> Ulli Horlacher in de.comp.os.unix.apps.misc:

>>>> | user15@o15:~/ybtra-o15$ echo 'scale=0; 2^255-19' | bc -lq | tr '\012' '~' | sed -e 's/\\~//g' | tr '~' '\012'
>>>> | 57896044618658097711785492504343953926634992332820282019728792003956564819949
>>>
>>>framstag@juhu:~: perl -Mbigint -wle 'print 2**255-19'
>>>57896044618658097711785492504343953926634992332820282019728792003956564819949
>>
>> Da müßte ich dann aber alles auf Perl umstellen, was
>> ich eigentlich nicht vorhabe.
>
>Wieso?
>Du musst doch nur diese eine Zeile ersetzen.
>Aber alles auf Perl umstellen ist sowieso eine gute Idee, das macht dein
>Programm wesentlich robuster.
>Fehlerbehandlung in sh-Skripten ist UHHAERXXX.

Es handelt sich hier nicht um sh-Scripts, sondern es sind
'program files' (Scripts) für bc.

Wenn ich die in Perl schreiben würde, müßte ich mich zu-
nächst einmal mit den entsprechenden Eigenschaften und
Limitationen von Perl auseinandersetzen.

>> Das Beispiel war wohl eher flacsh gewählt von mir, denn
>> ich habe hier auch ein paar bc-Scripts, die mehrere Zei-
>> len ausgeben. Auf die soll das 'Entfalten' nämlich auch
>> anwendbar sein.
>
>Die nach Perl zu transformieren duerfte trivial sein.

Kann schon sein. Ich weiß ja, daß Du gern Perl 'bewirbst'. :-)

Marcel
--
─╮ ╭───╮ ╭───────╮ ..26..╭──╮ ╭────╮ ╭─╮ ╭─╮ ╭───╮ ╭──╮
╰─╮ │ ╰─╮ ╰─────╮ │ ╭─╮ ╭─╯ │ ╭──╯ ╭─╯ │ ╰─╯ │ ╰─╮ ╰───╯ │ ╭─
╭─╯ ╰──╮ ╰────╮ ╭─╯ ╰─╯ ╰─╯ ╭─╯ ╰─╮ │ ╭──╯ │ ╭─╯ ..63..╰─╯
╰───────╯ ╰─╯ ╰──────╯ ╰─╯ ╰──╯ ..67..

Helmut Waitzmann

unread,
Apr 10, 2023, 6:26:55 PM4/10/23
to
Marcel Logen <33320000...@ybtra.de>:

[«bc»‐Verwendung]

> Meine Fragen dazu:

[…]

> 2. Übergabe von Werten und expressions
>
> Beim OpenBSD-bc kann man per Option "-e" expressions übergeben,
> bevor ein Script-File abgearbeitet wird. Das ist AFAICS beim GNU-
> bc nicht möglich: Dort wird STDIN erst nach Abarbeitung der Files
> gelesen, so daß ich vor dem Ausführen von Scripts keine Variablen-
> Werte auf der command line angeben kann. Es gibt allerdings die
> extension "read()". Hier jedoch kann man nur 'reine' Zahlen, aber
> keine expressions (Programm-Code) übergeben. Auch umständlich,
> wenn ich z. B. die Zahl "2^255-19" einspeisen will.
>
> Gibt es da für GNU-bc eine Lösung?
>

Ich weiß keine, die nicht umständlich ist.  Ich denke in
die Richtung, in einem Wrapper‐Shell‐Skript zuerst die
«bc»‐Ausdrücke in eine (temporäre) Datei zu schreiben und
dann die temporäre Datei mittels Eingabeumlenkung zu
öffnen, zu entfernen und an «bc» einen Namen, der der
geöffneten Datei (file descriptor) entspricht, zu
übergeben:

Fragment des Wrapper‐Bash‐Skripts:

if tempdir="$( mktemp --directory )"
then
if
printf > "${tempdir%/}"/ausdruecke.bc \
'%s\n' hier die bc-Ausdruecke hinschreiben &&
exec {fd}< "${tempdir%/}"/ausdruecke.bc
then
ok() { return 0 ; }
else
ok() { return 1 ; }
fi
{
rm -Rf -- "$tempdir"
ok &&
} 3<&-
exec bc -Optionen… -- /dev/fd/"$fd" restliche bc-Parameter
else
exit 2
fi

Lästig an dem zu schreibenden Wrapper‐Bash‐Skript ist das
Parsen und (teilweise) Interpretieren der übergebenen
Parameter.  Anschließend müssen alle (außer der Option «-e»
mitsamt ihrem Parameter) an «bc» übergeben werden, wobei
der Name für die geöffnete Datei («/dev/fd/"$fd"») als
erster Dateiparameter übergeben werden muss.

Dass ich die Datei vor dem Aufruf von «bc» entfernen lasse,
hat den Zweck, zu ermöglichen, dass «bc» nicht als
Extra‐Prozess läuft sondern den Wrapper‐Shell‐Prozess
ersetzt (siehe das Shell‐Kommando «exec»).  Dadurch, dass
der Prozess nach dem Start von «bc» kein Shell mehr ist,
kann man natürlich auch kein nachträgliches Entfernen der
Datei vornehmen.  Deshalb muss sie vor dem Start von «bc»
entfernt werden.  Damit ihr Inhalt «bc» noch zur Verfügung
steht, muss sie zuvor geöffnet worden sein:  Sie wird
dadurch zu einer geöffneten namenlosen (also temporären)
Datei, die automatisch vom Dateisystem verschwindet, sobald
sie nicht mehr geöffnet ist, und der Zugriff ist nur über
den Namen «/dev/fd/"$fd"» möglich.

Marcel Logen

unread,
Apr 15, 2023, 5:07:40 AM4/15/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

> Fragment des Wrapper‐Bash‐Skripts:

Danke. Bei der Analyse Deines Codes bin ich auf ein seltsames
Verhalten der bash gestoßen:

> exec {fd}< "${tempdir%/}"/ausdruecke.bc

| user14@n14:/tmp$ cat hallo9
| hallo

| user14@n14:/tmp$ exec {asdf}< hallo9
| user14@n14:/tmp$ declare -p asdf
| declare -- asdf="10"

OK, wie zu erwarten.

| user14@n14:/tmp$ unset asdf
| user14@n14:/tmp$ declare -p asdf
| bash: declare: asdf: not found

Dann ohne "exec":

| user14@n14:/tmp$ {asdf}< hallo9

Keine (sichtbare) Reaktion der Shell. Und:

| user14@n14:/tmp$ declare -p asdf
| bash: declare: asdf: not found

Mir ist nicht klar, was da eigentlich passiert, wenn ich kein
"exec" angebe.

Mal ein wenig gespielt:

| user14@n14:/tmp$ {asdf;}< hallo9
| bash: syntax error near unexpected token `}'

| user14@n14:/tmp$ {asdf ;}< hallo9
| bash: syntax error near unexpected token `}'

| user14@n14:/tmp$ {asdf ; }< hallo9
| bash: syntax error near unexpected token `}'

| user14@n14:/tmp$ { asdf ; }< hallo9
| bash: asdf: command not found

Mit der ksh unter OpenBSD wird ohne "exec" das Terminalfenster
geschlossen, was für mich auf das erwartete Verhalten hindeutet:
Der Befehl nach "exec" ersetzt die laufende Shell.

Noch zwei Punkte, die mir auffielen (oder gehören die besser
in die Ursprungsgruppe dcouam? Grübel):

> {
> rm -Rf -- "$tempdir"
> ok &&
^^ Wozu ist das nötig?

> } 3<&-
^^^^ Und wozu das? (Der file descriptor 3 wird offenbar
geschlossen.)

Marcel

f'up2 de.comp.os.unix.shell

Marcel Logen

unread,
Apr 15, 2023, 6:03:15 AM4/15/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

> Marcel Logen <33320000...@ybtra.de>:

[«bc»‐Verwendung]
>> 2. Übergabe von Werten und expressions
[...]
>> wenn ich z. B. die Zahl "2^255-19" einspeisen will.
>>
>> Gibt es da für GNU-bc eine Lösung?
>
> Ich weiß keine, die nicht umständlich ist.  Ich denke in
> die Richtung, in einem Wrapper‐Shell‐Skript zuerst die
> «bc»‐Ausdrücke in eine (temporäre) Datei zu schreiben und
> dann die temporäre Datei mittels Eingabeumlenkung zu
> öffnen, zu entfernen und an «bc» einen Namen, der der
> geöffneten Datei (file descriptor) entspricht, zu
> übergeben:
>
> Fragment des Wrapper‐Bash‐Skripts:
>
> if tempdir="$( mktemp --directory )"

Hier würde mir auch eine Datei reichen. Oder hat es einen beson-
deren Grund, daß Du ein Verzeichnis erstellen läßt?

if tempfil="$( mktemp )"

> then
> if
> printf > "${tempdir%/}"/ausdruecke.bc \
> '%s\n' hier die bc-Ausdruecke hinschreiben &&
> exec {fd}< "${tempdir%/}"/ausdruecke.bc

Das würde ich so schreiben:

> "$tempfil" printf '%s\n' "$1" && exec {fd}< "$tempfil"

So wird *mir* die Struktur klarer.

> then
> ok() { return 0 ; }
> else
> ok() { return 1 ; }
> fi
> {
> rm -Rf -- "$tempdir"

Das wäre dann nicht nötig.

> ok &&
> } 3<&-

Wie im anderen Posting gesagt: Das habe ich noch nicht verstanden.

> exec bc -Optionen… -- /dev/fd/"$fd" restliche bc-Parameter

exec bc -q -- /dev/fd/"$fd" "$2"

sollte doch funktionieren, wenn ich beim Aufruf des Wrappers nur
zwei Argumente angebe.

> else
> exit 2
> fi

Wobei dann $1 die Ausdrücke wären und $2 das jeweils aufgerufene
bc-Script. Also so:

./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea

Siehe z. B.
<https://groups.google.com/g/de.test/c/tuLbQd3W29o/m/rTP6RjmMAQAJ>,
wo bc-eea mein bc-Script für den erweiterten euklidischen Algorith-
mus ist und a[0] und b[0] die Eingabewerte, die auf der command
line angegeben werden sollen. Das gesuchte Ergebnis ist s[0], das
multiplikative Inverse von 5 mod 2^255-19.

> Lästig an dem zu schreibenden Wrapper‐Bash‐Skript ist das
> Parsen und (teilweise) Interpretieren der übergebenen
> Parameter.  Anschließend müssen alle (außer der Option «-e»
> mitsamt ihrem Parameter) an «bc» übergeben werden, wobei
> der Name für die geöffnete Datei («/dev/fd/"$fd"») als
> erster Dateiparameter übergeben werden muss.

-e spielt hier bei GNU-bc keine Rolle, da es diese Option da nicht
gibt. Deren Verhalten soll ja gerade emuliert werden.

Und wenn ich die bc-Ausdrücke in halbe Anführungszeichen setze,
sollten sie ja als *ein* Parameter ($1) aufgefaßt werden, oder?

Marcel

Marcel Logen

unread,
Apr 15, 2023, 6:06:21 AM4/15/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

> Marcel Logen <33320000...@ybtra.de>:

[«bc»‐Verwendung]
>> 2. Übergabe von Werten und expressions
[...]
>> wenn ich z. B. die Zahl "2^255-19" einspeisen will.
>>
>> Gibt es da für GNU-bc eine Lösung?
>
> Ich weiß keine, die nicht umständlich ist.  Ich denke in
> die Richtung, in einem Wrapper‐Shell‐Skript zuerst die
> «bc»‐Ausdrücke in eine (temporäre) Datei zu schreiben und
> dann die temporäre Datei mittels Eingabeumlenkung zu
> öffnen, zu entfernen und an «bc» einen Namen, der der
> geöffneten Datei (file descriptor) entspricht, zu
> übergeben:
>
> Fragment des Wrapper‐Bash‐Skripts:
>
> if tempdir="$( mktemp --directory )"

Hier würde mir auch eine Datei reichen. Oder hat es einen beson-
deren Grund, daß Du ein Verzeichnis erstellen läßt?

if tempfil="$( mktemp )"

> then
> if
> printf > "${tempdir%/}"/ausdruecke.bc \
> '%s\n' hier die bc-Ausdruecke hinschreiben &&
> exec {fd}< "${tempdir%/}"/ausdruecke.bc

Das würde ich so schreiben:

> "$tempfil" printf '%s\n' "$1" && exec {fd}< "$tempfil"

So wird *mir* die Struktur klarer.

> then
> ok() { return 0 ; }
> else
> ok() { return 1 ; }
> fi
> {
> rm -Rf -- "$tempdir"

Das wäre hier nicht unbedingt nötig, da /tmp beim Neustart des
Rechners geleert wird.

> ok &&
> } 3<&-

Wie im anderen Posting gesagt: Das habe ich noch nicht verstanden.

> exec bc -Optionen… -- /dev/fd/"$fd" restliche bc-Parameter

exec bc -q -- /dev/fd/"$fd" "$2"

sollte doch funktionieren, wenn ich beim Aufruf des Wrappers nur
zwei Argumente angebe.

> else
> exit 2
> fi

Wobei dann $1 die Ausdrücke wären und $2 das jeweils aufgerufene
bc-Script. Also so:

./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea

Siehe z. B.
<https://groups.google.com/g/de.test/c/tuLbQd3W29o/m/rTP6RjmMAQAJ>,
wo bc-eea mein bc-Script für den erweiterten euklidischen Algorith-
mus ist und a[0] und b[0] die Eingabewerte, die auf der command
line angegeben werden sollen. Das gesuchte Ergebnis ist s[0], das
multiplikative Inverse von 5 mod 2^255-19.

> Lästig an dem zu schreibenden Wrapper‐Bash‐Skript ist das
> Parsen und (teilweise) Interpretieren der übergebenen
> Parameter.  Anschließend müssen alle (außer der Option «-e»
> mitsamt ihrem Parameter) an «bc» übergeben werden, wobei
> der Name für die geöffnete Datei («/dev/fd/"$fd"») als
> erster Dateiparameter übergeben werden muss.

-e spielt hier bei GNU-bc keine Rolle, da es diese Option da nicht
gibt. Deren Verhalten soll ja gerade emuliert werden.

Und wenn ich die bc-Ausdrücke in halbe Anführungszeichen setze,
sollten sie ja als *ein* Parameter ($1) aufgefaßt werden, oder?

Marcel 3b6lb (3513003)

[supersedes]
--
╭──────────╮ ╭───╮ ╭───╮ ╭─╮ ╭─╮ ╭──╮
╭─╯ ╭───╯ ╭─╮ ╭──╯ │ ╰─╮ ╰─╯ ╰─╯ │ │ ╰─╮
│ ╭─╯ ╭───╮ ╭──╯ │ ╰──╮ │ ╭──╮ ╭─╯ ╰─╮ ╰──╮ ╰───
────╯ ╰────╯ ╰─╯ ╰─────╯ ╰─╯ ╰───╯ 408cc6 ╰─────╯

Helmut Waitzmann

unread,
Apr 15, 2023, 11:16:36 PM4/15/23
to
Marcel Logen <33320000...@ybtra.de>:
> Helmut Waitzmann in de.comp.os.unix.apps.misc:
>
>> Marcel Logen <33320000...@ybtra.de>:

>> if tempdir="$( mktemp --directory )"
>
> Hier würde mir auch eine Datei reichen. Oder hat es einen beson-
> deren Grund, daß Du ein Verzeichnis erstellen läßt?

Das ist eine Vorsichtsmaßnahme:  Falls das Dateisystem, in dem
die temporäre Datei erzeugt werden soll, über NFS verteilt wird,
ist das Erzeugen einer Datei im Gegensatz zum Erzeugen eines
Verzeichnisses keine unteilbare (atomare) Operation.

> if tempfil="$( mktemp )"
>
>> then
>> if
>> printf > "${tempdir%/}"/ausdruecke.bc \
>> '%s\n' hier die bc-Ausdruecke hinschreiben &&
>> exec {fd}< "${tempdir%/}"/ausdruecke.bc
>
> Das würde ich so schreiben:
>
> > "$tempfil" printf '%s\n' "$1" && exec {fd}< "$tempfil"
>
> So wird *mir* die Struktur klarer.

Ja, bei simple commands dürfen die Umlenkungen sogar ganz vorne
stehen; das stimmt (habe ich bisher aber nicht in der Gewohnheit).

>> then
>> ok() { return 0 ; }
>> else
>> ok() { return 1 ; }
>> fi
>> {
>> rm -Rf -- "$tempdir"
>
> Das wäre hier nicht unbedingt nötig, da /tmp beim Neustart des
> Rechners geleert wird.

Das ist Dateisystem‐Hygiene.  Ich weiß ja nicht, wieviel in die
Datei reinkommen soll, und erst recht nicht, wie oft das Skript
laufen wird, bis das System einen Neustart erfährt.

[…]

>> exec bc -Optionen… -- /dev/fd/"$fd" restliche bc-Parameter
>
> exec bc -q -- /dev/fd/"$fd" "$2"
>
> sollte doch funktionieren, wenn ich beim Aufruf des Wrappers nur
> zwei Argumente angebe.

Das ist der Grund, warum ich mein Skript ausdrücklich «Fragment»
genannt habe:  Eigentlich müsste es zuerst die übergebenen
Parameter – die ja allesamt (außer den Optionen «-e» mit ihren
jeweiligen Parametern) an «bc» weitergereicht werden sollen –
untersuchen, die Option «-e» mit ihrem jeweiligem Parameter
herausfischen und diese Parameter in die Aufrufparameter des
«printf»‐Kommandos, das die temporäre Datei füllt, stecken.  Die
restlichen Parameter müsste es darauf hin untersuchen, wo die
«bc»‐Optionen enden und die übergebenen Dateinamen beginnen.

Dann müsste es an «bc» die Optionen, danach die temporäre Datei
und schließlich die restlichen Dateiparameter übergeben.

Ich vermute, dass ich den Aufwand im allgemeinen nicht machen
wollte, sondern in der Praxis lieber darauf verzichten würde, die
«bc»‐Option «-e» überhaupt zu benutzen (auch wenn sie wirklich
sehr wünschenswert ist).

>
>> else
>> exit 2
>> fi
>
> Wobei dann $1 die Ausdrücke wären und $2 das jeweils aufgerufene
> bc-Script. Also so:
>
> ./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea
>

Ja.  Wenn man sich darauf beschränken will, dass der «bc»‐Wrapper
nur dafür geeignet ist, genau eine Option «-e» mit ihrem
Parameter zu simulieren und genau einen Namen einer an «bc» zu
übergebenden Datei entgegenzunehmen, dann reicht das so.
Da kann ich nicht viel damit anfangen:  Mein Firefox mit
abgestelltem Javascript zeigt mir das in einer kaum lesbaren Form
an.

Immerhin kann ich erkennen, dass das vor kurzem in «de.test»
eingestellt wurde.  Allerdings hat mir «de.test» vorhin mit
1,5 GB mein Dateisystem zugeknallt[1], so dass ich gezwungen war,
«de.test» zu leeren.

[1] Dort wütet jemand, der seit Tagen mehrmals pro Sekunde das
immergleiche Posting mit gefälschter Absenderadresse einstellt,
und diejenigen Newsserver, von denen ich News beziehe, liefern
mir halt den Müll.

> wo bc-eea mein bc-Script für den erweiterten euklidischen Algorith-
> mus ist und a[0] und b[0] die Eingabewerte, die auf der command
> line angegeben werden sollen. Das gesuchte Ergebnis ist s[0], das
> multiplikative Inverse von 5 mod 2^255-19.
>
>> Lästig an dem zu schreibenden Wrapper‐Bash‐Skript ist das
>> Parsen und (teilweise) Interpretieren der übergebenen
>> Parameter.  Anschließend müssen alle (außer der Option «-e»
>> mitsamt ihrem Parameter) an «bc» übergeben werden, wobei
>> der Name für die geöffnete Datei («/dev/fd/"$fd"») als
>> erster Dateiparameter übergeben werden muss.
>
> -e spielt hier bei GNU-bc keine Rolle, da es diese Option da nicht
> gibt. Deren Verhalten soll ja gerade emuliert werden.

Ja, genau.  Dafür muss das «bc»‐Wrapper‐Skript alle an es
übergebenen Parameter darauf hin untersuchen, ob es sie
unverändert an «bc» weiterreicht oder – im Fall der Option «-e»
mitsamt deren Parameter – selber verarbeitet und für den
GNU‐«bc»‐Aufruf umsetzt.

> Und wenn ich die bc-Ausdrücke in halbe Anführungszeichen setze,
> sollten sie ja als *ein* Parameter ($1) aufgefaßt werden, oder?

Ja.  Dann macht der Shell einen einzigen Parameter daraus und
übergibt ihn dem Wrapper‐Skript.  Sofern «bc» damit zurechtkommt,
müsste das funktionieren.  Beispielsweise enthalten
Funktionsdefinitionen in «bc» zwingend ein Newline‐Zeichen, das
man nicht durch einen Strichpunkt ersetzen kann.  Man braucht
also mindestens 2 «-e»‐Optionen dafür, wenn man nicht das
Newline‐Zeichen in den Parameter packen will.  (Das kriegt der
Shell zwar hin, ist aber – wenn man sich auf den POSIX‐Standard
beschränken will – nicht gerade anwenderfreundlich einzutippen.)

Marcel Logen

unread,
Apr 16, 2023, 8:36:54 AM4/16/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

>Marcel Logen <33320000...@ybtra.de>:

[...]

>> exec bc -q -- /dev/fd/"$fd" "$2"
>>
>>sollte doch funktionieren, wenn ich beim Aufruf des Wrappers nur zwei
>>Argumente angebe.

[...]

>>Wobei dann $1 die Ausdrücke wären und $2 das jeweils aufgerufene
>>bc-Script. Also so:
>>
>> ./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea
>
>Ja.  Wenn man sich darauf beschränken will, dass der «bc»‐Wrapper nur
>dafür geeignet ist, genau eine Option «-e» mit ihrem Parameter zu
>simulieren und genau einen Namen einer an «bc» zu übergebenden Datei
>entgegenzunehmen, dann reicht das so.

Ich werde Dein Fragment mal entsprechend anpassen und es dann
damit versuchen. Danke noch mal für Deine Mühe.

>>Siehe z. B.
>><https://groups.google.com/g/de.test/c/tuLbQd3W29o/m/rTP6RjmMAQAJ>,
>
>Da kann ich nicht viel damit anfangen:  Mein Firefox mit abgestelltem
>Javascript zeigt mir das in einer kaum lesbaren Form an.

Grmbl!

Mal interessehalber: Wie hast Du Deinem Firefox denn das JavaScript
abgewöhnt? Ich dachte, das geht heute mit Bordmitteln nicht mehr.
Ein AddOn will ich mir dafür nicht installieren.

Groogle Groups ist inzwischen ein Krampf, da man u. a. nicht mehr
die Message-ID ermitteln kann, weil es keinen Posting-Quelltext gibt.

>Immerhin kann ich erkennen, dass das vor kurzem in «de.test» eingestellt
>wurde.  Allerdings hat mir «de.test» vorhin mit 1,5 GB mein Dateisystem
>zugeknallt[1], so dass ich gezwungen war, «de.test» zu leeren.
>
>[1] Dort wütet jemand, der seit Tagen mehrmals pro Sekunde das
>immergleiche Posting mit gefälschter Absenderadresse einstellt, und
>diejenigen Newsserver, von denen ich News beziehe, liefern mir halt den
>Müll.

de.test ist momentan der zweite Krampf, siehe dazu die Artikel in
<news:de.admin.net-abuse.news>.

>>wo bc-eea mein bc-Script für den erweiterten euklidischen Algorith-
>>mus ist und a[0] und b[0] die Eingabewerte, die auf der command
>>line angegeben werden sollen. Das gesuchte Ergebnis ist s[0], das
>>multiplikative Inverse von 5 mod 2^255-19.

Versuche es statt mit Google Groups einmal hiermit (die Message-ID
habe ich mit einigen Verrenkungen wieder herausgefunden):

<http://al.howardknight.net/?STYPE=msgid&MSGI=%3C20230401sa103123%40o15.ybtra.de%3E>

Dort gibt es die Kommandozeile

| $ bc -q bc-eea | tr [...]

mit ihrem Output.

In diesem Fall hatte ich die Werte a[0] und b[0] direkt in das
bc-Script "bc-eea" hineinschreiben müssen. Umständlich.

Da würde ich also jetzt mit dem Wrapper folgendes eingeben können:

./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea

Und wohl im Wrapper selbst beim Aufruf von bc noch die Umgebungs-
variable BC_LINE_LENGTH=0, wie von Dir vorgeschlagen. (BTW: Diese
Möglichkeit gibt es beim OpenBSD-bc nicht, wie ich sah.)

[...]

Marcel 3hv0v (3734559)
--
───╮ ╭──╮ ╭─────╮ ╭──╮ ╭───────╮ ╭──────╮ ╭───╮ ╭───╮ ╭─
╭─╯ ╭─╯ │ │ ╰─╯ │ ╰─────╮ │ │ │ │ │ ╰─╮ │ ╭─╯
╰───╯ ╰───╯ ╭──╯ ╭──╮ │ ╰───╯ ╭───╯ │ │ ╭──╯ ╰─╮ │
╰──────╯ ╰──╯ ╰─────╯ ╰────╯b02e11╰─╯

Helmut Waitzmann

unread,
Apr 17, 2023, 7:12:01 PM4/17/23
to
Marcel Logen <33320000...@ybtra.de>:
> Helmut Waitzmann in de.comp.os.unix.apps.misc:
>
>> Marcel Logen <33320000...@ybtra.de>:
>
> [...]
>
>>> exec bc -q -- /dev/fd/"$fd" "$2"
>>>
>>> sollte doch funktionieren, wenn ich beim Aufruf des Wrappers
>>> nur zwei Argumente angebe.
>
> [...]
>
>>> Wobei dann $1 die Ausdrücke wären und $2 das jeweils
>>> aufgerufene bc-Script. Also so:
>>>
>>> ./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea
>>
>> Ja.  Wenn man sich darauf beschränken will, dass der
>> «bc»‐Wrapper nur dafür geeignet ist, genau eine Option «-e» mit
>> ihrem Parameter zu simulieren und genau einen Namen einer an
>> «bc» zu übergebenden Datei entgegenzunehmen, dann reicht das so.

[…]

>>> Siehe z. B.
>>> <https://groups.google.com/g/de.test/c/tuLbQd3W29o/m/rTP6RjmMAQAJ>,
>>
>> Da kann ich nicht viel damit anfangen:  Mein Firefox mit
>> abgestelltem Javascript zeigt mir das in einer kaum lesbaren
>> Form an.
>
> Grmbl!
>
> Mal interessehalber: Wie hast Du Deinem Firefox denn das JavaScript
> abgewöhnt? Ich dachte, das geht heute mit Bordmitteln nicht mehr.
> Ein AddOn will ich mir dafür nicht installieren.

Ich verwende dazu das AddOn «noscript».  Was geschieht, wenn man
statt dessen «javascript.enabled» auf «false» setzt, habe ich
nicht ausprobiert, meine aber, gelesen zu haben, dass der Firefox
dann nicht mehr funktioniert, weil er auch intern mit Javascript
arbeitet.

Möglicherweise lässt es sich auch noch direkt in der Datei
«user.js» (im Profilverzeichnis) abstellen:

// Global Security Policies (Search in the Release Notes for "Security
// Policies" to learn more about this):
// <http://kb.mozillazine.org/Security_Policies#top>
// <http://www.mozilla.org/projects/security/components/ConfigPolicy.html>
//
// Predefined security levels are "noAccess", "sameOrigin", "allAccess".
// <http://www.mozilla.org/projects/security/components/same-origin.html>
// Other values are privilege names (used with signed scripts).
//
// Eine Ausnahme sind die Konfigurationselemente
// "capability.policy.<policyname>.javascript.enabled": Mit ihnen wird
// Javascript (fuer die vereinbarten policy names oder default) ein- oder
// ausgeschaltet. Deshalb gibt es als Wert nur "noAccess" oder "allAccess".
// "sameOrigin" hat dort keine Bedeutung. See
// <http://www.mozilla.org/projects/security/components/ConfigPolicy.html#levels>.
//
// default policy:
//
user_pref("capability.policy.default.javascript.enabled", "noAccess");
user_pref("capability.policy.default.Window.open", "noAccess");
user_pref("capability.policy.default.Window.status", "noAccess");
user_pref("capability.policy.default.Window.sidebar", "noAccess");
user_pref("capability.policy.default.Window.print", "noAccess");

Aber da wissen die Fachleute in
«de.comm.software.mozilla.browser» sicher besser Bescheid.

[…]

> Versuche es statt mit Google Groups einmal hiermit (die
> Message-ID habe ich mit einigen Verrenkungen wieder
> herausgefunden):
>
> <http://al.howardknight.net/?STYPE=msgid&MSGI=%3C20230401sa103123%40o15.ybtra.de%3E>

Ja, das kann ich lesen.


> Dort gibt es die Kommandozeile
>
>
> | $ bc -q bc-eea | tr [...]
>
> mit ihrem Output.
>
>
> In diesem Fall hatte ich die Werte a[0] und b[0] direkt in das
> bc-Script "bc-eea" hineinschreiben müssen. Umständlich.

Ich würde das sogar als inakzeptabel ansehen, denn «bc-eea» soll
ja ein (unveränderliches) Programm sein, während die Zuweisungen
bei jedem Aufruf aufs Neue wählbare Parameter sein sollen.

> Da würde ich also jetzt mit dem Wrapper folgendes eingeben
> können:
>
> ./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea

Ja, genau.  Eine andere Möglichkeit wäre noch, «bc» so
aufzurufen:

{ printf '%s\n' 'a[0]=5' 'b[0]=2^55-19' &&
cat -- bc-eea
} | bc -q | …

Das schiebt zuerst die zwei Zuweisungen in «bc» rein und
anschließend das, was «cat» liefert: den Inhalt der Datei
«bc-eea» (a useful use of «cat»).

Marcel Logen

unread,
Apr 20, 2023, 4:21:30 PM4/20/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

> Marcel Logen <33320000...@ybtra.de>:

[...]

Gut. Ich hoffe nur, daß ich Dich durch den Groups-Google-Link nicht
dazu verleitet habe, de.test mit dem Newsreader zu besuchen, und Du
deshalb daraufhin die 1,5 GB Müll herunterladen und anschließend wie-
der entsorgen mußtest. :-(

[Eingabewerte direkt ins bc-Script eintragen]
> Ich würde das sogar als inakzeptabel ansehen, denn «bc-eea» soll
> ja ein (unveränderliches) Programm sein, während die Zuweisungen
> bei jedem Aufruf aufs Neue wählbare Parameter sein sollen.
>
>> Da würde ich also jetzt mit dem Wrapper folgendes eingeben
>> können:
>>
>> ./bc-wrapper 'a[0]=5; b[0]=2^255-19' bc-eea
>
> Ja, genau.  Eine andere Möglichkeit wäre noch, «bc» so
> aufzurufen:
>
> { printf '%s\n' 'a[0]=5' 'b[0]=2^55-19' &&
> cat -- bc-eea
> } | bc -q | …
>
> Das schiebt zuerst die zwei Zuweisungen in «bc» rein und
> anschließend das, was «cat» liefert: den Inhalt der Datei
> «bc-eea» (a useful use of «cat»).

Diese Lösung gefällt mir sehr gut!

Läßt sich - mit Semikolon - auch sehr schön als Einzeiler schrei-
ben (die nutze ich sehr gern), den man dann per shell history im-
mer wieder verwenden kann.

Ein Wrapper-Script ist dann gar nicht nötig.

Da ich das bc-Script "bc-eea" auf einem anderen Debian-Rechner
habe, probiere ich es hier erst mal so aus:

| user14@n14:/tmp$ cat bc-test01
| c=a*b
| c

| user14@n14:/tmp$ { printf '%s\n' 'a=3' 'b=5^2' && cat -- bc-test01 ; } | bc
| 75
| user14@n14:/tmp$

Prima, funktioniert also prinzipiell so.

Danke für Deine Anregungen.

[noch mal zitiert:]
> (a useful use of «cat»).

Ich hatte mich auch gefragt, ob es hier evtl. mit einer Umlenkung
geht, aber damit bin ich nicht weitergekommen.

Marcel
--
Debian GNU/Linux 11 (bullseye)

Marcel Logen

unread,
Apr 20, 2023, 4:43:23 PM4/20/23
to
Helmut Waitzmann in de.comp.os.unix.apps.misc:

>Marcel Logen <33320000...@ybtra.de>:

[...]

Danke. Ich werde mir die Links mal ansehen.

>Aber da wissen die Fachleute in «de.comm.software.mozilla.browser»
>sicher besser Bescheid.

Ich leite mal dahin um.

Marcel 3o2j7 (3934823)

f'up2 de.comm.software.mozilla.browser
--
╭──────╮ ╭────────────────╮ ╭─╮ ╭──╮
─╮ │ ╭───╯ ╰────────────╮ │ │ ╰───╯ │
│ │ │ ╭─────╮ ╭────╮ ╭───────╮ ╭──╯ ╰───╯ ╭─╯ ╭───────╮
╰─╯ ╰──╯ ╰───╯ ╰─╯ ╰─╯ ╰─────╯ 467f79╰──╮

Helmut Waitzmann

unread,
Apr 23, 2023, 1:46:00 AM4/23/23
to
Marcel Logen <33320000...@ybtra.de>:
> Helmut Waitzmann in de.comp.os.unix.apps.misc:
>> { printf '%s\n' 'a[0]=5' 'b[0]=2^55-19' &&
>> cat -- bc-eea
>> } | bc -q | …

> Läßt sich - mit Semikolon - auch sehr schön als Einzeiler schrei-
> ben (die nutze ich sehr gern), den man dann per shell history im-
> mer wieder verwenden kann.

Ja sicher.  Im Usenet versuche ich, keine langen
Shell‐Kommandozeilen zu schreiben, weil sie nicht gut automatisch
neuumbrochen werden können.  Meine Beiträge sollen auch mit
schmalen Anzeigegeräten noch lesbar sein, ohne dass man sie
neuumbrechen muss.
0 new messages