[SOLVED] Bash '||' OR operator not working in Perl?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm trying to make a little Perl script to mount/umount devices on the command line.. I came up with the following
but in line 8 the '||' operator is not working (its works by itself on the command line)... BTW the scripts uses a while loop so I can keep toggling mount/umount devices.
Code:
while ( <<>> ) {
system "clear";
@devices=`lsblk -f | egrep -w 'mmcblk.|sd.' | awk '{print\$1" "\$3" "\$7}'`;
foreach $index (0..$#devices) {
print "$index: $devices[$index]";
}
$index = $_;
system "udisksctl mount -b /dev/$devices[$index] > /dev/null 2>&1 || umount /dev/$devices[$index]";
print "Enter an index number: ";
}
Last edited by young_jedi; 03-17-2019 at 05:10 PM.
I'm trying to make a little Perl script to mount/umount devices on the command line.. I came up with the following
but in line 8 the '||' operator is not working (its works by itself on the command line)... BTW the scripts uses a while loop so I can keep toggling mount/umount devices.
Code:
while ( <<>> ) {
system "clear";
@devices=`lsblk -f | egrep -w 'mmcblk.|sd.' | awk '{print\$1" "\$3" "\$7}'`;
foreach $index (0..$#devices) {
print "$index: $devices[$index]";
}
$index = $_;
system "udisksctl mount -b /dev/$devices[$index] > /dev/null 2>&1 || umount /dev/$devices[$index]";
print "Enter an index number: ";
}
the condition you're using needs to give back a status of completion or a fail of completion in order to execute any further code within that statement.
Code:
is true no echo
[[ -d /usr ]] || echo "yes"
is false because there is a /usr
it fires an echo
[[ ! -d /usr ]] || echo "no"
checks the return value within the brackets ( ) so it can act upon it.
therefore it should be written like this.
Code:
# if mounted then un-mount && , or if not mounted then mount ||
[[$(system "udisksctl mount -b /dev/$devices[$index] > /dev/null 2>&1) ]] &&
umount /dev/$devices[$index]" ||
mount /dev/$devices[$index]";
but written in perl script, not bash. Though I am not sure in perl if that is a true ternary operator in perl either.
this is better sutied for your perl script The ternary operator in Perl
Thanks for replying, Perl is a glue programming language so it should execute bash code natively (I don't have to do what you're saying in a bash script). But I see what you're saying about surrounding it in brackets to capture the return status and having that factor in on whether the next command should run or not. Ill check to see how to do that in Perl and if that works, thank you..
Last edited by young_jedi; 03-17-2019 at 08:11 PM.
see this
Note that the default shell for the system() in Unix is sh -c -- not sure what the default is for Linux. Might be bash, but you'd need to check.
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,799
Rep:
Quote:
Originally Posted by young_jedi
Thanks for replying, Perl is a glue programming language so it should execute bash code natively (I don't have to do what you're saying in a bash script). But I see what you're saying about surrounding it in brackets to capture the return status and having that factor in on whether the next command should run or not. Ill check to see how to do that in Perl and if that works, thank you..
Check the "perlfunc" manpage for the "system()" call. I think what you're attempting to do in a single system() call may need to be split into two calls. The example on that page:
@scasey, You can omit the parens as long as it doesnt change the meaning of the code.
@rnturn, Thats I good idea I'll try braking it up into variables, and if that doesnt work ill try two system calls thanks.. Im trying to write elegant code....
Last edited by young_jedi; 03-19-2019 at 06:45 PM.
@rnturn thanks it works now though I cant get >/dev/null 2>&1 to work for the same reason... But besides that it all works perfectly..
Code:
This is free software..
#!/usr/bin/perl
$simulate_return='xdotool key Return ; xdotool key Return';
system $simulate_return;
while ( <> ) {
system 'clear';
@devices=`lsblk -f | egrep -w 'mmcblk.|sd.' | awk '{print\$1" "\$3" "\$7}'`;
foreach $index (0..$#devices) {
print "$index: $devices[$index]";
}
print "\n", 'Choose an index number: ';
$selected = <>;
system $simulate_return;
$mount="udisksctl mount -b /dev/$devices[$selected]";
$umount="udisksctl unmount -b /dev/$devices[$selected]";
system( $mount ) == 0 || system( $umount );
}
I'm marking this thread as solved, but if anyone knows how I cant get the '>/dev/null 2>&1' part to work that will be great! I even tried using the long form, e.g.:
Code:
$mount="udisksctl mount -b /dev/$devices[$selected] >/dev/null 2>&1";
$umount="udisksctl unmount -b /dev/$devices[$selected]";
unless ( !system $mount ) {
system $umount;
}
Last edited by young_jedi; 03-21-2019 at 11:18 PM.
Basically im using bash's OR '||' operator to toggle between mount/umount.. If the device is already mounted
then it will unmount it, but in the process the mount command will return in error.. I want to "hide" that error
by redirecting STDERR to /dev/null.. But its not working.. If you notice in my working code above I removed
'>/dev/null 2>&1' cause it broke the script..
Last edited by young_jedi; 03-21-2019 at 11:16 PM.
true >/dev/null 2>&1 || echo "true(1) gave error"
false >/dev/null 2>&1 || echo "false(1) gave error"
result:
Code:
false(1) gave error
Try this in perl:
Code:
#!/usr/bin/perl -w
use strict;
system ('false >/dev/null 2>&1') == 0 || system ('echo "false(1) gave error"');
system ('true >/dev/null 2>&1') == 0 || system ('echo "true(1) gave error"');
result:
Code:
false(1) gave error
Note: there is a well known problem here: in shell 0=success, other=errorcode; in C/Perl/etc 0=false, 1=true.
(It would be less problematic, if false(1) would be called fail(1), and true(1) would be called success(1).)
So you're saying the nonzero return values are actually true (backwords from the traditional "0 but true" notion that the shell uses). If that's the case than all I should have to do is remove the negation (!) operator, but somehow I don't think that's going to work... Cause i'm pretty sure I tried that already, but i'll try it again.. But rather what if the bash command is giving a nonzero exit status that actually indicates success (as they can return whatever their programmed to), is that a possability? Anyway thanks for bringing that to my attention, I didn't know that until now.
Last edited by young_jedi; 03-23-2019 at 07:22 PM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.