简体   繁体   English

从 perl 脚本中获取 alpine linux 上的 zsh 上的“无法执行“命令””错误

[英]Getting `Can't exec "command"` error on zsh on alpine linux from inside a perl script

I've got a perl wrapper script for taskwarrior's task command that runs perfectly fine on macos.我有一个用于 taskwarrior 的task命令的 perl 包装器脚本,它在 macOS 上运行得很好。

I've ported it to a docker container running alpine.我已经将它移植到运行 alpine 的 docker 容器中。 When I run the script, I get this weird error:当我运行脚本时,我得到了这个奇怪的错误:

> # bin/task_wrapper.pl task list
Wrapper command: command task   list
Can't exec "command": No such file or directory at bin/task_wrapper.pl line 61.

On my mac, it works just fine, no error.在我的 mac 上,它工作得很好,没有错误。

which command reports: command: shell built-in command on both mac and on docker alpine. which command报告: command: shell built-in command

I can run command task list directly from the command line in docker container and works fine.我可以直接从 docker 容器中的命令行运行command task list并且工作正常。

Here's the whole script:这是整个脚本:


#! /usr/bin/env perl

use strict;
use warnings;

my $context;
my $runsub = shift @ARGV;

my @show_cmds = qw( done delete add modify );

{ no strict 'refs';
    &${runsub}(@ARGV) if $runsub;
}

# my @tw_cmds = qw ( add annotate append calc config context count delete denotate done duplicate edit execute export help import log logo modify prepend purge start stop synchronize undo version );

my @descriptors = qw ( due: dep: depends: attribute: status: priority: pri: due: after: start: before: end: );

sub _parse {
    my @bits =  @_;
    # find the first element that contains a command
    my $count = 0;
    my @ids;
    my @rest = @bits;
    foreach my $b (@bits) {
        if ( $b =~ /([[a-f][0-9]]{8}),*/ ) {
            push @ids, $1;
            shift @rest;
            next;
        }
        if ( $b =~ /(\d[\d\-]*),*/ ) {
            push @ids, $1;
            shift @rest;
            next;
        }
        last;
    }

    return \@ids, \@rest;
}

sub task {
    my $args = $_[0] || '';
    my $filter = '';
    my $subcmd = '';
    if (ref $args) {
        $filter = %$args{'filter'} || '';
        $subcmd = %$args{'subcmd'} || '';
        shift @_;
    }
    my @args = @_;
    my @a = qw ( command task );
    $context = $ENV{FLEXIBLE_CONTEXT} if !$context;
    if ($context && $args ne 'sync') {
        push @a, 'rc.context=' . $context;
    }
    if ($args =~ /sync/) {
        exec 'command task sync';
    } else {
        print "Wrapper command: @a $filter $subcmd @args \n";
        ################ ERROR ON LINE BELOW
        system("@a $filter $subcmd @args");
        ################
    }

    # show updated list of tasks
    my $show;
    $show = grep { $subcmd eq $_ } @show_cmds if $subcmd;
    if ($show) {
        my @sub_args;
        push @sub_args, 'limit:3' if !$context;
        push (@sub_args, '+st') if $context && $context !~ /\+sn|\+st/;
        task ({}, @sub_args);
    }
    #print @a;
    #print $ENV{FLEXIBLE_CONTEXT};
    return;
}

sub ta {
    task ({subcmd => 'add' }, @_ );
}

sub tm {
    my ($ids, $rest) = _parse(@_);
    task ({subcmd => 'modify', filter => "@$ids"}, @$rest);
}

# delete task
sub tdel {
    my ($ids, $rest) = _parse(@_);
    task ({subcmd => 'delete', filter => "@$ids"}, @$rest);
}

# done task
sub td {
    task ('done', @_);
}
sub tl {
    task ('next', "\\($ENV{'PU'} or +qst\\)", "-BLOCKED", @_);
}

sub tai {
    task ('add', $ENV{'PU'}, 'due:1h', @_);
}

You say you're using zsh , and zsh does have a builtin named command , but you're not using zsh .您说您正在使用zsh ,并且zsh确实有一个名为command的内置命令,但您没有使用zsh You're using /bin/sh since你正在使用/bin/sh因为

system( SHELL_CMD )

is effectively short for实际上是

system( '/bin/sh', '-c', SHELL_CMD )

(It's technically the value returned by perl -V:sh , not /bin/sh . But that value is /bin/sh .) (从技术上讲,这是perl -V:sh返回的值,而不是/bin/sh 。但该值是/bin/sh 。)

If you want to issue a zsh command, you will need to run zsh instead of /bin/sh .如果要发出zsh命令,则需要运行zsh而不是/bin/sh

system( 'zsh', '-c', SHELL_CMD )

Note that "@a $filter $subcmd @args" is not the proper way to build a shell command.请注意, "@a $filter $subcmd @args"不是构建 shell 命令的正确方法。 It suffers from code injection bugs.它存在代码注入错误。 You should use String::ShellQuote 's shell_quote .您应该使用String::ShellQuoteshell_quote

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM