If
you have a question on how to do something in Perl, or
you need a Perl solution to an actual real-life problem, or
you're unsure why something you've tried just isn't working...
then this section is the place to ask.
However, you might consider asking in the chatterbox first (if you're a
registered user). The response time tends to be quicker, and if it turns
out that the problem/solutions are too much for the cb to handle, the
kind monks will be sure to direct you here.
format error: file is too short
at /usr/share/perl5/Archive/Zip/Archive.pm line 1031.
Archive::Zip::Archive::_findEndOfCentralDirectory(Archive::Zip::Ar
+chive=HASH(0x56216520bf48), IO::File=GLOB(0x562165214f30)) called at
+/usr/share/perl5/Archive/Zip/Archive.pm line 761
Archive::Zip::Archive::readFromFileHandle(Archive::Zip::Archive=HA
+SH(0x56216520bf48), IO::File=GLOB(0x562165214f30), "/tmp/invalid.xlsx
+") called at /usr/share/perl5/Archive/Zip/Archive.pm line 729
Archive::Zip::Archive::read(Archive::Zip::Archive=HASH(0x56216520b
+f48), "/tmp/invalid.xlsx") called at /usr/share/perl5/Spreadsheet/Par
+seXLSX.pm line 63
Spreadsheet::ParseXLSX::parse(Spreadsheet::ParseXLSX=HASH(0x562165
+1e94d8), "/tmp/invalid.xlsx") called at ./quiete_xlsx line 8
eval {...} called at ./quiete_xlsx line 7
Dear community, I'm just coding a little diameter avp converion and I need to pad the AVP string. According to RFC 3588, AVP string
that do not align on a 32-bit boundary MUST have the necessary padding 00.
examples (space between values is only to shown better and should be removed on final string):
Hi Monks!
My Perl utility generates a bash script that consists of mkdir/rsync/cp commands.
This bash script is later used by users (this means that I don't want to actually run those commands when my utility runs, rather just to generate the script).
Given a UNIX path, I need to do two different actions - depending on the path type (dir or file):
1. If the path is a directory, then just create it using mkdir.
2. If the path is a file, then just copy the file from the dir directory using rsync or cp (depending if user specified a machine to copy from).
For example, consider this:
The utility works good, unless a path contains "special chars".
I tried to deal with it by escaping and using quotes but I can't seem to cover all cases.
By "special chars" I mean chars like ":",";","(",")","_",....
I tried to use the following to subs:
sub escape {
my ($path) = @_;
if ($path =~ /\\/) {
$path =~ s/\\/\\\\/g;
}
if ($path =~ /\$/) {
$path =~ s/\$/\\\$/g;
}
return $path;
}
sub wrap_with_quotes {
my ($path) = @_;
if ($path =~ /( |\;|\!)/) {
return '"'.$path.'"';
}
return $path;
}
But it also failed for a lot of cases and it escaped alot of unneeded chars (like ".", "/", etc. - which are valid in paths without escaping).
The code looks like:
foreach my $dir (sort(keys(%dirs))) {
$dir = escape($dir);
$dir = wrap_with_quotes($dir);
print("mkdir -p /tmp/$dir\n");
}
foreach my $file (sort(keys(%files))) {
my $parent_dir = dirname($file);
my $abs_path = abs_path($file);
$abs_path = escape($abs_path);
$abs_path = wrap_with_quotes($abs_path);
$parent_dir = escape($parent_dir);
$parent_dir = wrap_with_quotes($parent_dir);
print("cp $abs_path /tmp/$parent_dir\n");
}
foreach my $file (sort(keys(%remote_files))) {
my $parent_dir = dirname($file);
my $abs_path = abs_path($file);
my $host = get_host();
$abs_path = escape($abs_path);
$abs_path = wrap_with_quotes($abs_path);
$parent_dir = escape($parent_dir);
$parent_dir = wrap_with_quotes($parent_dir);
print("rsync -a $host$abs_path /tmp/$parent_dir\n");
}
I of course want to support any kind of path. For example, the special char could contain a "\" before it, and then I need to escape both of them.
I built a small test for you to understand what I'm after:
declare -a special_chars=("!" "@" "#" "$" "%" "^" "_" "-" "=" "+" "["
+"]" "(" ")" "{" "}" "'" ":" "," "." ";" " " "\"" "<" ">")
if [ "$1" == 1 ]; then # create playground (before running the bash sc
+ript)
for special_char in "${special_chars[@]}"; do
mkdir -p "/test1/a${special_char}b"
touch "/test1/a${special_char}b/data"
done
else # test playground output (after running the bash script)
for special_char in "${special_chars[@]}"; do
mkdir -p "/tmp/test1/a${special_char}b"
if [ "$?" -ne 0 ]; then
exit 1
fi
done
fi
If 1 is passed to the script, it will generate directory with one special char (for example: test1/a;b).
Then I run the generated bash script and then the test script again - if 0 is passed, it will check if the bash script successfully created dirs & copied files into /tmp.
Hope it makes sense.
I also noticed that rsync and cp except different escaping. For example, "/test1/a;b/data" works for cp and "/test1/a\;b/data" works for rsync.
Is there an easy way to handle special chars in path? All I want is to create mkdir/cp/rsync commands in a bash script that so they will later work.
Please help me to fix the wrap_with_quotes and escape subs or find a better way.
Dear community, I'm trying to create a little server who handles multiple clients connections (at least 10). Below the current code that works perfect using fork. At least it accepts several connections from clients.
With the below code, I have the following behaviour:
- Client ask for connection ==> Accepted ==> OK
- Client sent packet ==> Received and printed ==> OK
- Client sent another packet ==> Not received ==> NOK
Most probably, the while cicle will be activated only for each connection request, so that's the reason because I cannot retrieve other packets.
Could someone help me please to adjust the below code? What I need is establish one (or more) client connection, then client send data continuosly (without disconnection) and server should reply on each packet it receives.
Thank you
Lucas
#!/usr/bin/perl -w
use IO::Socket::INET;
$SIG{CHLD} = sub {wait ()};
my $socket = new IO::Socket::INET (
LocalHost => '0.0.0.0',
LocalPort => '5000',
Proto => 'tcp',
Listen => 5,
Reuse => 1);
die "cannot create socket $!n" unless $socket;
while ($new_sock = $socket->accept()) {
$pid = fork();
die "Cannot fork: $!" unless defined($pid);
if ($pid == 0) { # This is the fork child
$new_sock->recv(my $data, 500);
print "$data\n";
}
}
In the perl source, we find various modules in the 'cpan', 'dist' and 'ext' directories.
What are the rules that determine which of those 3 directories houses which modules ?
For example, why is it that POSIX is in the 'ext' directory, but threads is in the 'dist' directory ? (Why not the other way round ? Or why aren't they both in the same directory ?)
I have an odd problem that's hurting my head: I'm trying to construct an RE that will only match if the letter in any position does *NOT* match any other character in the string. I'm constructing this RE with a perl program and building the RE from a template. It is the *template* that says "these letters should be distinct" and then I want to run through a few thousand words to pick out the words that "match".
For example, my "template" might look like this: "abcdefa" and I already have the code that generates (.)?????\1. I can't figure how to make the "?"s say "these guys all have to be distinct".
Hi Monks!
I have a array of hashes. Each hash contains a rexes rule. Given a path, I'm trying to iterate over the rules and find the first matching rule.
I'm trying to add a small feature which will help users to debug (since the rexes are user custom) - I want to mark the groups in the given path. For example:
# Given path: /a/b/c/d
# Given regex: ^/a/b/([^/]*)/([^\/]*)
# Output: /a/b/\033[1;31mc\033[0m/\033[1;31md\033[0m
The @captures contains the group values that were captured (c and d in the example). I came a cross with the Term::ANSIColor module which can help me color the string without writing the color codes myself.
So, what would be the best way to create a variable $output that is basically $path but colored given the captured groups? You can assume that there are always at least two groups.
I have a list of time strings in the HH:MM:SS format. I want to add each to a variable set with localtime and compare it to a timestamp later in the script. I'm having trouble understanding how to add that HH:MM:SS string to the localtime variable.
#! /usr/bin/perl
use Time::Piece;
use strict;
my(@times) = ("00:05:21","00:08:05","00:10:33");
my $startTime = localtime();
print "Start: ", $startTime, $/;
foreach my $t (@times) {
sleep 2;
my $newTime = localtime();
my $ss = $startTime + $t; ### this is where I need advice
if($ss > $newTime){
print "\$ss is greater.\n";
### execute some functions here
}
print "Newtime: ", $newTime, $/;
my $diff = $newTime - $startTime;
print $diff, $/;
Snippets of code should be wrapped in
<code> tags not<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).