我有一个perl包装脚本taskwarrior的task
命令在macos上运行得很好。
我已经把它移植到一个运行alpine的docker容器上。当我运行脚本时,我得到了这个奇怪的错误:
> # 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.
在我的mac上,它工作得很好,没有错误。
which command
报告mac和docker alpine上的command: shell built-in command
。
我可以直接从命令行运行command task list
在docker容器和工作良好。
这是整个脚本:
#! /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', @_);
}
你说你正在使用zsh
,而zsh
确实有一个名为command
的内置,但你没有使用zsh
。你在使用/bin/sh
,因为
system( SHELL_CMD )
是
的缩写system( '/bin/sh', '-c', SHELL_CMD )
(从技术上讲,它是perl -V:sh
返回的值,而不是/bin/sh
。但是这个值是/bin/sh
。)
如果你想发出zsh
命令,你需要运行zsh
而不是/bin/sh
。
system( 'zsh', '-c', SHELL_CMD )
请注意,"@a $filter $subcmd @args"
不是构建shell命令的正确方式。它受到代码注入错误的困扰。你应该使用String::ShellQuote的shell_quote
.