Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

wrapping bash and astronomy

by Aldebaran (Curate)
on Feb 27, 2023 at 06:33 UTC ( [id://11150627] : perlquestion . print w/replies, xml ) Need Help??

Aldebaran has asked for the wisdom of the Perl Monks concerning the following question:

I'm eager to get 2022 off my machine and stowed away for the next year I have to deal with email and google, and I'm hoping it's not 2023. I think I have largely achieved de-google-isation of my scripts. I have a variety of smallish utility scripts that I wrote on uphill side of the learning curve of re-hosting with gitlab that I would like to wrap with perl. I've kicked the can forward on a number of fronts with approximating geological problems with highway data, where we were getting pretty deep in the weeds of a changing context. I don't have a map yet, but I've got a better idea what the hosting requirements will need to be. I have a grab-bag of semi-related issues, the common thread being that I want to do it in perl.

ephemeris

Q1) Are these points on the same meridian as my eyeball suggests? What is the best-fit "line?"

Q2) From these data, can we make any arguments about "betweenness?" This was such a beautful display first with the crescent moon, venus, then Jupiter, while Aldebaran tends the sheep and guards the Sisters. (I find some sky myths "believable" if they don't involve zombie carpenters.)

fritz@laptop:~/Documents$ ./1.2023.pl ./1.2023.pl Name Right Ascension Declination Jupiter 0.179353375287228 0.0559955210059931 Venus 0.0955771968036561 0.0254452716279536 Moon 0.655478796651881 0.262724424143006 Aldeb 1.20392811802569 0.288139315093836 Time is Fri Feb 24 20:32:39 2023 Julian day is 2460000.64767361 fritz@laptop:~/Documents$

Edit: removed 2 lines of unuseful source.

Source:

#!/usr/bin/perl use Time::Piece; use Astro::Coord::ECI::Utils 'deg2rad'; use Astro::Coords; my $log_conf4 = '/home/fritz/Documents/perlmonks/conf_files/3.conf'; Log::Log4perl::init($log_conf4); #info my $logger = Log::Log4perl->get_logger(); $logger->info("$0"); $logger->info("Name\tRight Ascension\t\tDeclination"); for my $name (qw/Jupiter Venus Moon/) { my $planet2 = Astro::Coords->new( planet => $name ); $planet2->datetime( Time::Piece->new ); my $ra = $planet2->ra( format => q/rad/ ); my $dec = $planet2->dec( format => q/rad/ ); $logger->info("$name\t$ra\t$dec"); } my $aldeb_ra_degrees = 68.98; my $aldeb_ra_radians = deg2rad($aldeb_ra_degrees); my $aldeb_declination_degrees = 16.509166666667; my $aldeb_dec_radians = deg2rad($aldeb_declination_degrees); $logger->info("Aldeb\t$aldeb_ra_radians\t$aldeb_dec_radians "); my $t = localtime; my $jd = $t->julian_day; $logger->info("Time is $t"); $logger->info("Julian day is $jd"); __END__

For SSCCE followers in need of a conf file for Log::Log4perl:

###################################################################### +######### # Log::Log4perl Conf + # ###################################################################### +######### log4perl.rootLogger = INFO, LOG1, SCREEN log4perl.appender.SCREEN = Log::Log4perl::Appender::Screen log4perl.appender.SCREEN.stderr = 0 log4perl.appender.SCREEN.layout = Log::Log4perl::Layout::PatternLayou +t log4perl.appender.SCREEN.layout.ConversionPattern = %m %n log4perl.appender.LOG1 = Log::Log4perl::Appender::File log4perl.appender.LOG1.filename = /home/hogan/Documents/hogan/logs/4. +log4perl.txt log4perl.appender.LOG1.mode = append log4perl.appender.LOG1.layout = Log::Log4perl::Layout::PatternLayou +t log4perl.appender.LOG1.layout.ConversionPattern = %d %p %m %n

wrapping scripts with perl

Calling External Commands More Safely has been a haukex post and forum standard for system calls. I'd like to pursue this a bit and where it might not be just one line. Extending what I have:

fritz@laptop:~/Documents/gitlab1$ ./2.2023.pl Time is Sat Feb 25 17:09:31 2023 Julian day is 2460001.5066088 ./2.2023.pl Alnitak Alnilam Mintaka # systemx: Hello, World! # capturex: Hello, World! $VAR1 = 'Coordinates(ICRS,ep=J2000,eq=2000): 05 40 45.52666 -01 56 33 +.2649 (Opt ) A [5.19 2.29 90] 2007A&A...474..653V'; $VAR1 = 'Coordinates(ICRS,ep=J2000,eq=2000): 05 36 12.81335 -01 12 0 +6.9089 (Opt ) A [3.69 1.67 90] 2007A&A...474..653V'; $VAR1 = 'Coordinates(ICRS,ep=J2000,eq=2000): 05 32 00.40009 -00 17 5 +6.7424 (Opt ) A [4.92 2.38 90] 2007A&A...474..653V'; "git clone something" failed to start: "No such file or directory" at +./2.2023.pl line 43. fritz@laptop:~/Documents/gitlab1$ git clone something fatal: repository 'something' does not exist fritz@laptop:~/Documents/gitlab1$

Q3: How do I capture the 3 numeric fields for declination and Right Ascension, dealing with the potential minus sign?

Q4: How do I do a sanity check on these values without reinventing a wheel which someone else has almost certainly created already?

Above we see STDOUT as it plays the systemx stuff. I have the initial success with the stars that comprise Orion's belt, but I would say that everything that followed failed, at least to match the writer's intent. It would seem that they are not being interpreted by something that knows BASH. Perl source:

#!/usr/bin/perl use v5.030; use Time::Piece; use Log::Log4perl; my $t = localtime; my $jd = $t->julian_day; my $log_conf4 = '/home/fritz/Documents/perlmonks/conf_files/4.conf'; Log::Log4perl::init($log_conf4); #info my $logger = Log::Log4perl->get_logger(); $logger->info("Time is $t"); $logger->info("Julian day is $jd"); $logger->info("$0"); my @belt= qw/ Alnitak Alnilam Mintaka/; $logger->info("@belt"); use IPC::System::Simple qw/systemx capturex/; $logger->info("# systemx:"); systemx 'echo', 'Hello,', 'World!'; my $stdout = capturex 'echo', 'Hello,', 'World!'; $logger->info("# capturex: $stdout"); my @captured; for(@belt){ my $stdout = capturex 'perl', '1.simbad.pl', "$_"; push @captured, $stdout; } $logger->info("@captured"); #my $s1 = capturex 'set -eu'; # "set -eu" failed to start: "No such fi +le or directory" #$logger->info("s1 is $s1"); #my $s2 = capturex 'read repo'; # "read repo" failed to start: "No suc +h file or directory" #$logger->info("s2 is $s2"); my $group='perlmonks'; #my $repo = systemx 'read repo'; #$logger->info("s2 is $repo"); #my $command="git clone git/@gitlab.com:$group//$repo.git"; my $command="git clone something"; my $s3 = capturex "$command"; $logger->info("# capturex: $command"); $logger->info("# capturex output: $s3"); __END__

So, I'm shooting blanks for some reason and want to change tack. Let's try wrapping a bash script:

my $command="./5.git.sh"; my $s3 = capturex "$command"; $logger->info("# capturex: $command"); $logger->info("# capturex output: $s3");

I get the perl output but none of the bash script, which was helpful for what it was, and I'd like to write something like a perl equivalent for it:

#!/bin/bash pwd >README.md echo -n "Please enter email: " read email git config --global user.email $email ... git push -u origin master git push -u master origin

I also don't really know how to push and pull things yet, but that's part of the learning curve.

Anyways, so I'm looking for ways either wrap a bash script correctly or abrogate the wrapper by implementing it in perl.

Thanks for your comment,

Replies are listed 'Best First'.
Re: wrapping bash and astronomy
by hippo (Bishop) on Feb 27, 2023 at 09:47 UTC
    Anyways, so I'm looking for ways either wrap a bash script correctly or abrogate the wrapper by implementing it in perl.

    Git::Wrapper, perhaps?


    🦛

Re: wrapping bash and astronomy
by bliako (Monsignor) on Feb 28, 2023 at 19:10 UTC
    #my $s1 = capturex 'set -eu'; # "set -eu" failed to start: "No such file or directory"

    The usage is systemx("some_command",@args);. So: my $s1 = capturex 'set', '-eu'; The difference being that command and subsequent arguments must all be passed individually and not in one single string. The way you are calling it, it thinks that the whole string is one single command (and it complains it can't find it).

    HOWEVER! I assume that capturex, systemx and friends spawn a system command directly or via an ephemeral shell which ends as soon as the shell command ends. This means that a sequence of capturex calls will use completely different shells, which will not share any state. So, setting shell options via set -eu on one capturex call will not be preserved on the next capturex call. If you want to preserve state in a shell and execute many shell commands in it there is a simple way: first create a temporary shell script (see tempfile of File::Temp) within your perl-script to contain all the commands you want to run. And then execute this shell script via a single capturex call.

    Edit: Data::Dumper allows hiding the $VAR1 = section of its output if you set $Data::Dumper::Terse = 0; before first call. Similarly, perl2dump of Data::Roundtrip also allows terse output via perl2dump($vartodump, {'terse'=>1}); So you will have less text to filter out.

    Aldebaran++ I have to commend your efforts not only in using Perl but also in using Linux. It's a steep learning curve but it hides a ... springboard at the end of it. Plus the methodical approach you take in achieving your aims.

    bw, bliako

      The usage is systemx("some_command",@args);. So: my $s1 = capturex 'set', '-eu'; The difference being that command and subsequent arguments must all be passed individually and not in one single string. The way you are calling it, it thinks that the whole string is one single command (and it complains it can't find it).

      Ok, so it's clear now that have to tell it to find bash:

      my $capture = capturex "bash","2.create.bash", "@ARGV"; $logger->info("capx: $capture");

      I got a strong result with wrapping 2.create.bash, which I think is a nifty little utility for my nomenclature scheme.

      fritz@laptop:~/Documents/gitlab1$ ./4.wrap.pl 2.millcreek.pl Time is Thu Mar 2 01:43:55 2023 Julian day is 2460005.86383102 ./4.wrap.pl capx: The shebang is specifying bash Using bash 5.0.17(1)-release 2 3 3.millcreek.pl -rwxrwxr-x 1 fritz fritz 11K Mar 2 01:43 3.millcreek.pl fritz@laptop:~/Documents/gitlab1$
      HOWEVER! I assume that capturex, systemx and friends spawn a system command directly or via an ephemeral shell which ends as soon as the shell command ends. This means that a sequence of capturex calls will use completely different shells, which will not share any state. So, setting shell options via set -eu on one capturex call will not be preserved on the next capturex call. If you want to preserve state in a shell and execute many shell commands in it there is a simple way: first create a temporary shell script (see tempfile of File::Temp) within your perl-script to contain all the commands you want to run. And then execute this shell script via a single capturex call.

      I'm trying to follow, and I have a script to that end:

      #!/usr/bin/perl use v5.030; # strictness implied use warnings; use Path::Tiny; my ($path) = @ARGV; if (not defined $path) { die "Need path in\n"; } my $file_in = path("$path"); my @lines = $file_in->lines_utf8; my @matching; for my $line (@lines){ if ( $line =~ /^#*$/){ say "line matched $line"; next; } else { push( @matching, $line ); } } say @matching; say "cardinality: ", scalar @matching; my $target_dir = path('/tmp'); my $tempfile = $target_dir->tempfile('foobarXXXXXX'); $tempfile->spew("@matching"); # not atomic __END__

      Output. I can't figure out why the shebang and comments endure:

      fritz@laptop:~/Documents/gitlab1$ ./1.wrap.pl 3.git.sh line matched #!/bin/bash pwd >2.txt #echo "starting fresh with rm -rf .git" #rm -rf .git | tee 1.txt #git init #ls >README.md git add *.pl git add *.sh git add *.txt #git remote add origin git@gitlab.com:perlmonks/$1.git git commit -m 'next revision' | tee 2.txt git push -uf origin master | tee 2.txt #git push -uf master main | tee 2.txt cardinality: 13 fritz@laptop:~/Documents/gitlab1$

      Question: How is my regex not sieving out the comments? Do you see what I'm trying to pull off here?

      Aldebaran++ I have to commend your efforts not only in using Perl but also in using Linux. It's a steep learning curve but it hides a ... springboard at the end of it. Plus the methodical approach you take in achieving your aims.

      Woo-hoo, a springboard! If the board is at the height of Skylla, and extends to the center of Charybdis, how long does one fall until impact?

      Cheers,

        G'day Aldebaran,

        " can't figure out why the shebang and comments endure: ... How is my regex not sieving out the comments?"

        Your regex, /^#*$/, is anchored at the start (^) and end ($). Consider:

        $ perl -E ' my $x = "#shebang\n\nstatement1\n#comment\nstatement2"; my @lines = split /\n/, $x; say "All lines:"; say for @lines; say "-" x 40; say "Your regex:"; say for grep ! /^#*$/, @lines; say "-" x 40; say "Better regex:"; say for grep ! /^#/, @lines; say "-" x 40; ' All lines: #shebang statement1 #comment statement2 ---------------------------------------- Your regex: #shebang statement1 #comment statement2 ---------------------------------------- Better regex: statement1 statement2 ----------------------------------------

        Note how your regex is removing blank lines. Did you want that?

        Addendum: If the answer to that last question is yes, you can use /^(?:#|$)/.

        — Ken

Re: wrapping bash and astronomy
by Anonymous Monk on Feb 27, 2023 at 20:57 UTC
    #!/usr/bin/perl use strict; use warnings; use Astro::Coords; while (<DATA>) { # Q3: How do I capture the 3 numeric fields for declination and # Right Ascension, dealing with the potential minus sign? # Ignore the details, capture non-whitepsace: /:\s(\S+)\s(\S+)\s(\S+)\s+(\S+)\s(\S+)\s(\S+)\s/; my $ra = "$1 $2 $3"; my $dec = "$4 $5 $6"; print "$ra, $dec \n"; # Q4: How do I do a sanity check on these values # without reinventing a wheel which someone else # has almost certainly created already? # Feed this module: my $c = Astro::Coords->new( ra => $ra, dec => $dec, type => 'J2000'); print # sexagesimal $c->ra( format => 'sex'), ", ", $c->dec(format => 'sex'), "\n"; print # degrees $c->ra( format => 'deg'), ", ", $c->dec(format => 'deg'), "\n"; print # radians $c->ra( format => 'rad'), ", ", $c->dec(format => 'rad'), "\n\n"; } __DATA__ Coordinates(ICRS,ep=J2000,eq=2000): 05 40 45.52666 -01 56 33.2649 (Op +t ) A [5.19 2.29 90] 2007A&A...474..653V Coordinates(ICRS,ep=J2000,eq=2000): 05 36 12.81335 -01 12 06.9089 (Op +t ) A [3.69 1.67 90] 2007A&A...474..653V Coordinates(ICRS,ep=J2000,eq=2000): 05 32 00.40009 -00 17 56.7424 (Op +t ) A [4.92 2.38 90] 2007A&A...474..653V
    Output:
    05 40 45.52666, -01 56 33.2649 
    05:40:45.527, -01:56:33.26
    85.1896944166667, -1.94257358333333
    1.48684065633866, -0.0339043049914311
    
    05 36 12.81335, -01 12 06.9089 
    05:36:12.813, -01:12:06.91
    84.0533889583333, -1.20191913888889
    1.46700838478236, -0.0209774463163461
    
    05 32 00.40009, -00 17 56.7424 
    05:32:00.400, -00:17:56.74
    83.0016670416667, -0.299095111111111
    1.44865237452114, -0.00522019446550716
    

      Very nice, AM:,

      fritz@laptop:~/Documents/gitlab1$ ./3.2023.pl Time is Wed Mar 1 10:38:05 2023 Julian day is 2460005.23478009 ./3.2023.pl Alnitak Alnilam Mintaka $VAR1 = 'Coordinates(ICRS,ep=J2000,eq=2000): 05 40 45.52666 -01 56 33 +.2649 (Opt ) A [5.19 2.29 90] 2007A&A...474..653V'; $VAR1 = 'Coordinates(ICRS,ep=J2000,eq=2000): 05 36 12.81335 -01 12 0 +6.9089 (Opt ) A [3.69 1.67 90] 2007A&A...474..653V'; $VAR1 = 'Coordinates(ICRS,ep=J2000,eq=2000): 05 32 00.40009 -00 17 5 +6.7424 (Opt ) A [4.92 2.38 90] 2007A&A...474..653V'; 05 40 45.52666, -01 56 33.2649 05 36 12.81335, -01 12 06.9089 05 32 00.40009, -00 17 56.7424 ====== 05:40:45.527, -01:56:33.26 85.1896944166667, -1.94257358333333 1.48684065633866, -0.0339043049914311 05:36:12.813, -01:12:06.91 84.0533889583333, -1.20191913888889 1.46700838478236, -0.0209774463163461 05:32:00.400, -00:17:56.74 83.0016670416667, -0.299095111111111 1.44865237452114, -0.00522019446550716 fritz@laptop:~/Documents/gitlab1$

      Source:

      #!/usr/bin/perl use v5.030; use Time::Piece; use Log::Log4perl; use IPC::System::Simple qw/systemx capturex/; use Astro::Coords; my $t = localtime; my $jd = $t->julian_day; my $log_conf4 = '/home/fritz/Documents/perlmonks/conf_files/4.conf'; Log::Log4perl::init($log_conf4); #info my $logger = Log::Log4perl->get_logger(); $logger->info("Time is $t"); $logger->info("Julian day is $jd"); $logger->info("$0"); my @belt = qw/ Alnitak Alnilam Mintaka/; $logger->info("@belt"); my ( @captured, @processed ); for (@belt) { my $stdout = capturex 'perl', '1.simbad.pl', "$_"; push @captured, $stdout; } $logger->info("@captured"); for (@captured) { # Q3: How do I capture the 3 numeric fields for declination and # Right Ascension, dealing with the potential minus sign? # Ignore the details, capture non-whitepsace: $_ =~ m/:\s(\S+)\s(\S+)\s(\S+)\s+(\S+)\s(\S+)\s(\S+)\s/; my $ra = "$1 $2 $3"; my $dec = "$4 $5 $6"; print "$ra, $dec \n"; my $c = Astro::Coords->new( ra => $ra, dec => $dec, type => 'J2000' ); push @processed, $c; } say '======'; for (@processed) { print # sexagesimal $_->ra( format => 'sex' ), ", ", $_->dec( format => 'sex' ), "\n"; print # degrees $_->ra( format => 'deg' ), ", ", $_->dec( format => 'deg' ), "\n"; print # radians $_->ra( format => 'rad' ), ", ", $_->dec( format => 'rad' ), "\n\n +"; } __END__

      Here's a link to the wrapped, mini SIMBAD script for SSCCE purposes: 1.simbad.pl. I don't know what adding safeguards on failed matches might do, as I don't have another course than die'ing.

      Let me restate questions with this result:

      Q1) What is the best-fit "line" for the 3 Astro::Coords points of @processed?

      Q2) From these data, can we make any arguments about "betweenness?"

      Q2a) From these data, can we calculate the 3 angles formed of @processed? It seems to me that 2 of the angles are going to be less than 10 degrees, and the one with Alnilam at its vertex in the neighborhood of 160, and from this, we might say that Alnilam lies "between." (Distance from observer is not relevant in this view.)

      Cheers,