Using Config::Simple to read MySQL config file with keys without values - perl

I try to configure my mySql config file with perl.
I use config::simple for doing this.
my code is:
#!/bin/perl
use Config::Simple;
$cfg = new Config::Simple('/etc/mysql/my.cnf');
$cfg->param('bind-address', '192.168.1.11');
$cfg->save();
the problem is that I get an error when a row only has a key and not an value to it. How do I fix this problem?

To extend simbabque's comment I would suggest using Config::MySQL to deal with MySQL config files.
Config::MySQL extends Config::INI to support reading and writing
MySQL-style configuration files. Although deceptively similar to
standard .INI files, they can include bare boolean options with no
value assignment and additional features like !include and
!includedir.

Related

TOML how to have key without value

Many Python tools these days are using pyproject.toml as a config file, and mirror the tool's command line arguments with config file keys. Tools may have command line flags that are not passed any arguments:
sometool --some-flag
Now, I am trying to place this --some-flag into a pyproject.toml config file and can't figure out how to have a key without any value.
[tool.sometool]
# Both of the below are invalid
some-flag
some-flag =
In TOML, is it possible to have a key without a value?
This is not possible.
It'd depend on the tool how they are doing this, so please refer to their documentation. I would guess they are treating those flags as a boolean.
[tool.sometool]
some-flag = true

change SAS encoding to utf-8

I am struggling greatly with changing my SAS session to utf-8.
I have tried changing the cfg file - sasv9.cfg; however, I am told that access is denied
I have tried using the encoding option; however, it says I must apply this on start-up, I tried restarting SAS and entering it then, still no luck.
I have tried the locale function; however, it returns an invalid command warning.
I am pretty stuck here. I am using SAS base9.4 and I have tried to follow multiple different threads but cannot find a solution.
Copy the sasv9.cfg file from the location you do not have write access to a place you do (i.e. your Documents folder). Change the encoding in there.
Start SAS on the command line with -CONFIG "C:\path\to\cfg\sasv9.cfg"
That should force SAS to start the session with the new config file and the specified encoding.

Export Library path & include in perl

I have a query with regards to exporting library path & include for Platypus variant caller. The htslib it requires and platypus are installed on the server and I don't have sudo permissions to change them.
I am trying the following code to export library & include for running the caller. Am i missing osmething because am not able to execute it?
Code:
#!usr/perl-w
use strict;
use warnings;
`export LIBRARY_PATH=/opt/htslib/lib/`;
`export LD_LIBRARY_PATH=/opt/htslib/lib/`;
`export INCLUDE_PATH=/opt/htslib/include/`;
system ("python /opt/Platypus_0.8.1/Platypus.py callVariants --help");
Any sort of help would be appreciated.
You're setting the env vars of freshly-made shells, not of the Perl process that is to parent python. For that, you need the following:
$ENV{LIBRARY_PATH} = '/opt/htslib/lib/';
$ENV{LD_LIBRARY_PATH} = '/opt/htslib/lib/';
$ENV{INCLUDE_PATH} = '/opt/htslib/include/';
The last line of your code is better written as follows, since it avoids a needless shell:
system("python", "/opt/Platypus_0.8.1/Platypus.py", "callVariants", "--help");

Log4Perl: How do I change the logger file used from running code? (After a fork)

I have an ETL process set up in perl to process a number of files, and load them to a database.
Recently, for performance reasons I set up the code to be multi-threaded, through use of a fork() call and a call to system("perl someOtherPerlProcess.pl $arg1 $arg2").
I end up with about 12 instances of someOtherPerlProcess.pl running with different arguments, and these processes each work through one directories worth of files (corresponding to a single table in our database).
The applications main functions work, but I am having issues with figuring out how to configure my logging.
Ideally, I would like to have all the someOtherPerlProcess.pl share the same $log_config value to initialize their loggers, but have each of those create a log file in the directory they are working on.
I haven't been able to figure out how to do that. I also noticed that in the directory I am calling these perl scripts from I see several files (ARRAY(0x260eec), ARRAY(0x313f8), etc) that contain all my logging messages!
Is there a simple way to change the log4perl.appender.A1.filename value from running code?
Or to otherwise dynamically configure the file name we use, but use all other values from a config file?
I came up with a less than ideal solution for this, which is to configure my logger from someOtherPerlProcess.pl directly.
my $FORKED_LOG_CONF = "log4perl.appender.A1.filename=$directory_to_load/log.txt
log4perl.rootLogger=WARN, A1
log4perl.appender.A1=Log::Log4perl::Appender::File
log4perl.appender.A1.mode=append
log4perl.appender.A1.autoflush=1
log4perl.appender.A1.layout=PatternLayout
log4perl.appender.A1.layout.ConversionPattern=[%p] %d{yyyy-MM-dd HH:mm:ss}: %m%n";
#Logger start up
Log::Log4perl::init( \$FORKED_LOG_CONF);
my $logger = get_logger();
The $directory_to_load is the process specific portion of the logger, which works in the context of the perl process that is running and has a (local) value for that variable, but that method will fail if used in an external config file.
I would be happy to hear of any alternative solutions.
In your config file:
log4perl.appender.A1.filename=__LOGFILE__
In your script:
use File::Slurp;
my $log_cfg = read_file( $log_cfgfile );
my $logfile = "$directory_to_load/log.txt";
$log_cfg =~ s/__LOGFILE__/$logfile/;
Log::Log4perl::init( \$log_cfg );

How to handle this situatiuon in Perl

I am having a configuration INI file to store all configuration required for my script to run. I have a Logger.PM which uses Log4Perl, and ConfigReader.PM which reads the INI file and stores the value in global variable. My Start.PL is the entry point where i call the methods from Logger and configreader.
What I do currently
In Start.PL I hardcoded the INI file path
In Logger.Pm I harcoded the directory name where log files should be stored
What I want
I want the INI file path as configurable
I want the log folder path to be taken from the INI file
I could do this by following
Pass the INI file path as a parameter to the start.pl
Read the INI file and get the folder path from INI file
What I could face is that
I cannot use the Logger.PM in ConfigReader (partially) since the
folder name required for logger is part of INI file
I want to log every step of my script (for logging/debugging purpose in case of failure. )
I can use print but this will write to console and to capture i need to use >>log.txt. Then i will be forced to maintain 2 logs for my application which is not what I wanted
Anyone have a good solution for this scenario?
You can pass INI file path in command line using Getopt::Long, and command line switches for istance:
Start.pl --ini=/path/to/INI_file
Here is a code sample to show what changes are needed in Start.pl, in order to have switches:
#!/usr/bin/env perl
use v5.12;
use strict;
use Getopt::Long;
# That little tiny 's' after 'ini=' is for string
GetOptions ( 'ini=s' => \my $ini_file );
say $ini_file;
After this change, you can read all options from your INI file, including log folder path ( are you already using a module to manage INI files like Config::IniFiles? ).
There is something still unclear in your question about print: although one of my master said that print with a pair of square brackets is the best debugger in the world, why use print when you have set up Log::Log4perl?
When you say that Logger.PL can't be used in ConfigReader, are you referring to the log object?