如何按时间而不是按大小对 shell 脚本输入进行分块?

2023-12-28

在 bash 脚本中,我使用多生产者单消费者模式。生产者是将行写入 fifo 的后台进程(通过 GNU Parallel)。消费者从 fifo 读取所有行,然后排序、过滤并将格式化结果打印到 stdout。

然而,可能需要很长时间才能获得完整的结果。生产者通常在前几个结果上很快,但随后就会放慢速度。在这里,我更感兴趣的是每隔几秒查看一次数据块,每个数据块都单独排序和过滤。

mkfifo fifo
parallel ... >"$fifo" &
while chunk=$(read with timeout 5s and at most 10s <"$fifo"); do
  process "$chunk"
done

该循环将一直运行,直到所有生产者完成并且读取所有输入。每个块都会被读取,直到 5 秒内没有新数据,或者直到该块启动后 10 秒内没有新数据为止。如果 10 秒没有新数据,一个 chunk 也可能是空的。

我试图让它像这样工作:

output=$(mktemp)
while true; do
  wasTimeout=0 interruptAt=$(( $(date '+%s') + 10 ))
  while true; do
    IFS= read -r -t5 <>"${fifo}"
    rc="$?"
    if [[ "${rc}" -gt 0 ]]; then
      [[ "${rc}" -gt 128 ]] && wasTimeout=1
      break
    fi
    echo "$REPLY" >>"${output}"
    if [[ $(date '+%s') -ge "${interruptAt}" ]]; then
      wasTimeout=1
      break
    fi
  done
  echo '---' >>"${output}"
  [[ "${wasTimeout}" -eq 0 ]] && break
done

尝试了一些变体。在上面的形式中,它读取第一个块,但然后永远循环。如果我使用<"${fifo}"(如上所述,没有读/写)它在第一个块之后阻塞。也许所有这一切都可以简化为buffer and/or stdbuf?但它们都按大小而不是时间来定义块。


这不是一个需要解决的小问题。正如我所暗示的,C 程序(或除 shell 之外的某种编程语言的程序)可能是最好的解决方案。一些复杂的因素是:

  • 阅读时有超时。
  • 如果数据到达得足够快,超时就会改变。
  • Different systems have different sets of interval timing functions:
    • alarm() http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html可能随处可用,但只有 1 秒的分辨率,容易产生累积的舍入误差。 (编译此版本make UFLAGS=-DUSE_ALARM;在 macOS 上,使用make UFLAGS=-DUSE_ALARM LDLIB2=.)
    • setitimer() http://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html使用微秒计时和struct timeval类型。 (编译此版本make UFLAGS=-DUSE_SETITIMER;在 macOS 上,使用以下命令进行编译make UFLAGS=-DUSE_SETITIMER LDLIB2=.)
    • timer_create() http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html and timer_settime() http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime.html等使用现代纳秒类型struct timespec。这在 Linux 上可用;它在 macOS 10.14.5 Mojave 或更早版本上不可用。 (编译此版本make;它不适用于 macOS。)

程序使用消息是:

$ chunker79 -h
Usage: chunker79 [-hvV][-c chunk][-d delay][-f file]
  -c chunk  Maximum time to wait for data in a chunk (default 10)
  -d delay  Maximum delay after line read (default: 5)
  -f file   Read from file instead of standard input
  -h        Print this help message and exit
  -v        Verbose mode: print timing information to stderr
  -V        Print version information and exit

$

该代码可以在我的SOQ https://github.com/jleffler/soq(堆栈溢出问题)GitHub 上的存储库作为文件chunker79.c in the src/so-5631-4784 https://github.com/jleffler/soq/tree/master/src/so-5631-4784子目录。您还需要 src/libsoq 目录中的一些支持代码。

/*
@(#)File:           chunker79.c
@(#)Purpose:        Chunk Reader for SO 5631-4784
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 2019
*/

/*TABSTOP=4*/

/*
** Problem specification from the Stack Overflow question
**
** In a bash script I am using a many-producer single-consumer pattern.
** Producers are background processes writing lines into a fifo (via GNU
** Parallel).  The consumer reads all lines from the fifo, then sorts,
** filters, and prints the formatted result to stdout.
**
** However, it could take a long time until the full result is
** available.  Producers are usually fast on the first few results but
** then would slow down.  Here I am more interested to see chunks of
** data every few seconds, each sorted and filtered individually.
**
**    mkfifo fifo
**    parallel ... >"$fifo" &
**    while chunk=$(read with timeout 5s and at most 10s <"$fifo"); do
**      process "$chunk"
**    done
**
** The loop would run until all producers are done and all input is
** read.  Each chunk is read until there has been no new data for 5s, or
** until 10s have passed since the chunk was started.  A chunk may also
** be empty if there was no new data for 10s.
*/

/*
** Analysis
**
** 1.  If no data arrives at all for 10 seconds, then the program should
**     terminate producing no output.  This timeout is controlled by the
**     value of time_chunk in the code.
** 2.  If data arrives more or less consistently, then the collection
**     should continue for 10s and then finish.  This timeout is also
**     controlled by the value of time_chunk in the code.
** 3.  If a line of data arrives before 5 seconds have elapsed, and no
**     more arrives for 5 seconds, then the collection should finish.
**     (If the first line arrives after 5 seconds and no more arrives
**     for more than 5 seconds, then the 10 second timeout cuts in.)
**     This timeout is controlled by the value of time_delay in the code.
** 4.  This means that we want two separate timers at work:
**     - Chunk timer (started when the program starts).
**     - Delay timer (started each time a line is read).
**
** It doesn't matter which timer goes off, but further timer signals
** should be ignored.  External signals will confuse things; tough!
**
** -- Using alarm(2) is tricky because it provides only one time, not two.
** -- Using getitimer(2), setitimer(2) uses obsolescent POSIX functions,
**    but these are available on macOS.
** -- Using timer_create(2), timer_destroy(2), timer_settime(2),
**    timer_gettime(2) uses current POSIX function but is not available
**    on macOS.
*/

#include "posixver.h"

#include "stderr.h"
#include "timespec_io.h"
#include <assert.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <time.h>
#include <unistd.h>

#ifdef USE_SETITIMER
#include "timeval_math.h"
#include "timeval_io.h"
#include <sys/time.h>
#endif /* USE_SETITIMER */

static const char optstr[] = "hvVc:d:f:";
static const char usestr[] = "[-hvV][-c chunk][-d delay][-f file]";
static const char hlpstr[] =
    "  -c chunk  Maximum time to wait for data in a chunk (default 10)\n"
    "  -d delay  Maximum delay after line read (default: 5)\n"
    "  -f file   Read from file instead of standard input\n"
    "  -h        Print this help message and exit\n"
    "  -v        Verbose mode: print timing information to stderr\n"
    "  -V        Print version information and exit\n"
    ;

static struct timespec time_delay = { .tv_sec =  5, .tv_nsec = 0 };
static struct timespec time_chunk = { .tv_sec = 10, .tv_nsec = 0 };
static struct timespec time_start;

static bool verbose = false;

static void set_chunk_timeout(void);
static void set_delay_timeout(void);
static void cancel_timeout(void);
static void alarm_handler(int signum);

// Using signal() manages to set SA_RESTART on a Mac.
// This is allowed by standard C and POSIX, sadly.
// signal(SIGALRM, alarm_handler);

#if defined(USE_ALARM)

static void set_chunk_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    alarm(time_chunk.tv_sec);
    struct sigaction sa;
    sa.sa_handler = alarm_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

static void set_delay_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    unsigned time_left = alarm(0);
    if (time_left > time_delay.tv_sec)
        alarm(time_delay.tv_sec);
    else
        alarm(time_left);
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

static void cancel_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    alarm(0);
    signal(SIGALRM, SIG_IGN);
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

#elif defined(USE_SETITIMER)

static inline struct timeval cvt_timespec_to_timeval(struct timespec ts)
{
    return (struct timeval){ .tv_sec = ts.tv_sec, .tv_usec = ts.tv_nsec / 1000 };
}

static void set_chunk_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    struct itimerval tv_new = { { 0, 0 }, { 0, 0 } };
    tv_new.it_value = cvt_timespec_to_timeval(time_chunk);
    struct itimerval tv_old;
    if (setitimer(ITIMER_REAL, &tv_new, &tv_old) != 0)
        err_syserr("failed to set interval timer: ");
    struct sigaction sa;
    sa.sa_handler = alarm_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

static void set_delay_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    struct itimerval tv_until;
    if (getitimer(ITIMER_REAL, &tv_until) != 0)
        err_syserr("failed to set interval timer: ");
    struct timeval tv_delay = cvt_timespec_to_timeval(time_delay);

    if (verbose)
    {
        char buff1[32];
        fmt_timeval(&tv_delay, 6, buff1, sizeof(buff1));
        char buff2[32];
        fmt_timeval(&tv_until.it_value, 6, buff2, sizeof(buff2));
        err_remark("---- %s(): delay %s, left %s\n", __func__, buff1, buff2);
    }

    if (cmp_timeval(tv_until.it_value, tv_delay) <= 0)
    {
        if (verbose)
            err_remark("---- %s(): no need for delay timer\n", __func__);
    }
    else
    {
        struct itimerval tv_new = { { 0, 0 }, { 0, 0 } };
        tv_new.it_value = cvt_timespec_to_timeval(time_delay);
        struct itimerval tv_old;
        if (setitimer(ITIMER_REAL, &tv_new, &tv_old) != 0)
            err_syserr("failed to set interval timer: ");
        if (verbose)
            err_remark("---- %s(): set delay timer\n", __func__);
    }
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

static void cancel_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    struct itimerval tv_new =
    {
        .it_value    = { .tv_sec = 0, .tv_usec = 0 },
        .it_interval = { .tv_sec = 0, .tv_usec = 0 },
    };
    struct itimerval tv_old;
    if (setitimer(ITIMER_REAL, &tv_new, &tv_old) != 0)
        err_syserr("failed to set interval timer: ");
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

#else /* USE_TIMER_GETTIME */

#include "timespec_math.h"

static timer_t t0 = { 0 };

static void set_chunk_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);

    struct sigevent ev =
    {
        .sigev_notify = SIGEV_SIGNAL,
        .sigev_signo = SIGALRM,
        .sigev_value.sival_int = 0,
        .sigev_notify_function = 0,
        .sigev_notify_attributes = 0,
    };
    if (timer_create(CLOCK_REALTIME, &ev, &t0) < 0)
        err_syserr("failed to create a timer: ");

    struct itimerspec it =
    {
        .it_interval = { .tv_sec = 0, .tv_nsec = 0 },
        .it_value = time_chunk,
    };
    struct itimerspec ot;
    if (timer_settime(t0, 0, &it, &ot) != 0)
        err_syserr("failed to activate timer: ");

    struct sigaction sa;
    sa.sa_handler = alarm_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

static void set_delay_timeout(void)
{
    if (verbose)
        err_remark("-->> %s()\n", __func__);
    struct itimerspec time_until;
    if (timer_gettime(t0, &time_until) != 0)
        err_syserr("failed to set per-process timer: ");

    char buff1[32];
    fmt_timespec(&time_delay, 6, buff1, sizeof(buff1));
    char buff2[32];
    fmt_timespec(&time_until.it_value, 6, buff2, sizeof(buff2));
    err_remark("---- %s(): delay %s, left %s\n", __func__, buff1, buff2);

    if (cmp_timespec(time_until.it_value, time_delay) <= 0)
    {
        if (verbose)
            err_remark("---- %s(): no need for delay timer\n", __func__);
    }
    else
    {
        struct itimerspec time_new =
        {
            .it_interval = { .tv_sec = 0, .tv_nsec = 0 },
            .it_value = time_delay,
        };
        struct itimerspec time_old;
        if (timer_settime(t0, 0, &time_new, &time_old) != 0)
            err_syserr("failed to set per-process timer: ");
        if (verbose)
            err_remark("---- %s(): set delay timer\n", __func__);
    }
    if (verbose)
        err_remark("<<-- %s()\n", __func__);
}

static void cancel_timeout(void)
{
    if (timer_delete(t0) != 0)
        err_syserr("failed to delete timer: ");
}

#endif /* Timing mode */

/* Writing to stderr via err_remark() is not officially supported */
static void alarm_handler(int signum)
{
    assert(signum == SIGALRM);
    if (verbose)
        err_remark("---- %s(): signal %d\n", __func__, signum);
}

static void read_chunks(FILE *fp)
{
    size_t num_data = 0;
    size_t max_data = 0;
    struct iovec *data = 0;
    size_t buflen = 0;
    char *buffer = 0;
    ssize_t length;
    size_t chunk_len = 0;

    clock_gettime(CLOCK_REALTIME, &time_start);

    set_chunk_timeout();
    while ((length = getline(&buffer, &buflen, fp)) != -1)
    {
        if (num_data >= max_data)
        {
            size_t new_size = (num_data * 2) + 2;
            void *newspace = realloc(data, new_size * sizeof(data[0]));
            if (newspace == 0)
                err_syserr("failed to allocate %zu bytes data: ", new_size * sizeof(data[0]));
            data = newspace;
            max_data = new_size;
        }
        data[num_data].iov_base = buffer;
        data[num_data].iov_len = length;
        num_data++;
        if (verbose)
            err_remark("Received line %zu\n", num_data);
        chunk_len += length;
        buffer = 0;
        buflen = 0;
        set_delay_timeout();
    }
    cancel_timeout();

    if (chunk_len > 0)
    {
        if ((length = writev(STDOUT_FILENO, data, num_data)) < 0)
            err_syserr("failed to write %zu bytes to standard output: ", chunk_len);
        else if ((size_t)length != chunk_len)
            err_error("failed to write %zu bytes to standard output "
                      "(short write of %zu bytes)\n", chunk_len, (size_t)length);
    }

    if (verbose)
        err_remark("---- %s(): data written (%zu bytes)\n", __func__, length);

    for (size_t i = 0; i < num_data; i++)
        free(data[i].iov_base);
    free(data);
    free(buffer);
}

int main(int argc, char **argv)
{
    const char *name = "(standard input)";
    FILE *fp = stdin;
    err_setarg0(argv[0]);
    err_setlogopts(ERR_MICRO);

    int opt;
    while ((opt = getopt(argc, argv, optstr)) != -1)
    {
        switch (opt)
        {
        case 'c':
            if (scn_timespec(optarg, &time_chunk) != 0)
                err_error("Failed to convert '%s' into a time value\n", optarg);
            break;
        case 'd':
            if (scn_timespec(optarg, &time_delay) != 0)
                err_error("Failed to convert '%s' into a time value\n", optarg);
            break;
        case 'f':
            if ((fp = fopen(optarg, "r")) == 0)
                err_syserr("Failed to open file '%s' for reading: ", optarg);
            name = optarg;
            break;
        case 'h':
            err_help(usestr, hlpstr);
            /*NOTREACHED*/
        case 'v':
            verbose = true;
            break;
        case 'V':
            err_version("CHUNKER79", &"@(#)$Revision$ ($Date$)"[4]);
            /*NOTREACHED*/
        default:
            err_usage(usestr);
            /*NOTREACHED*/
        }
    }

    if (optind != argc)
        err_usage(usestr);

    if (verbose)
    {
        err_remark("chunk: %3lld.%09ld\n", (long long)time_chunk.tv_sec, time_chunk.tv_nsec);
        err_remark("delay: %3lld.%09ld\n", (long long)time_delay.tv_sec, time_delay.tv_nsec);
        err_remark("file:  %s\n", name);
    }

    read_chunks(fp);

    return 0;
}

我的 SOQ 存储库也有一个脚本gen-data.sh它利用一些自定义程序来生成如下数据流(种子值写入标准错误,而不是标准输出):

$ gen-data.sh
# Seed: 1313715286
2019-06-03 23:04:16.653: Zunmieoprri Rdviqymcho 5878 2017-03-29 03:59:15 Udransnadioiaeamprirteo
2019-06-03 23:04:18.525: Rndflseoevhgs Etlaevieripeoetrnwkn 9500 2015-12-18 10:49:15 Ebyrcoebeezatiagpleieoefyc
2019-06-03 23:04:20.526: Nrzsuiakrooab Nbvliinfqidbujoops 1974 2020-05-13 08:05:14 Lgithearril
2019-06-03 23:04:21.777: Eeagop Aieneose 6533 2016-11-06 22:51:58 Aoejlwebbssroncmeovtuuueigraa
2019-06-03 23:04:23.876: Izirdoeektau Atesltiybysaclee 4557 2020-09-13 02:24:46 Igrooiaauiwtna
2019-06-03 23:04:26.145: Yhioit Eamrexuabagsaraiw 9703 2014-09-13 07:44:12 Dyiiienglolqopnrbneerltnmsdn
^C
$

当送入chunker79使用默认选项,我得到如下输出:

$ gen-data.sh | chunker79
# Seed: 722907235
2019-06-03 23:06:20.570: Aluaezkgiebeewal Oyvahee 1022 2015-08-12 07:45:54 Weuababeeduklleym
2019-06-03 23:06:24.100: Gmujvoyevihvoilc Negeiiuvleem 8196 2015-08-29 21:15:15 Nztkrvsadeoeagjgoyotvertavedi
$

如果您分析时间间隔(查看输出行中的前两个字段),则该输出符合规范。更详细的分析如下:

$ timecmd -mr -- gen-data.sh | timecmd -mr -- chunker79
2019-06-03 23:09:14.246 [PID 57159] gen-data.sh
2019-06-03 23:09:14.246 [PID 57160] chunker79
# Seed: -1077610201
2019-06-03 23:09:14.269: Woreio Rdtpimvoscttbyhxim 7893 2017-03-12 12:46:57 Uywaietirkekes
2019-06-03 23:09:16.939: Uigaba Nzoxdeuisofai 3630 2017-11-16 09:28:59 Jnsncgoesycsevdscugoathusaoq
2019-06-03 23:09:17.845: Sscreua Aloaoonnsuur 5163 2016-08-13 19:47:15 Injhsiifqovbnyeooiimitaaoir
2019-06-03 23:09:19.272 [PID 57160; status 0x0000]  -  5.026s  -  chunker79
2019-06-03 23:09:22.084 [PID 57159; status 0x8D00]  -  7.838s  -  gen-data.sh
$

在该设置中,从输出到输出之间有一个明显的暂停。chunker79出现以及何时gen-data.sh完成。这是因为 Bash 等待管道中的所有进程完成,并且gen-data.sh直到消息完成后下次写入管道时才完成chunker79。这是此测试设置的产物;它不会成为问题中概述的 shell 脚本的一个因素。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何按时间而不是按大小对 shell 脚本输入进行分块? 的相关文章

  • 如何将命令作为参数传递给 ssh [重复]

    这个问题在这里已经有答案了 我的需要是让这个命令起作用 sshpass p XXXX ssh oStrictHostKeyChecking no email protected cdn cgi l email protection sudo
  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • apt-get install tzdata 非交互式

    当我尝试 apt get install y tzdata 将显示用于选择时区的命令行选项 我试图在脚本中使用它来进行一些设置 如何在没有用户输入的情况下使 apt get 运行 我知道重新配置 tzdata 我可以做 echo Ameri
  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 如何显示 zsh 函数定义(如 bash“type myfunc”)?

    如何在 zsh 中显示函数的定义 type foo没有给出定义 在bash中 bash function foo echo hello bash foo hello bash type foo foo is a function foo e
  • 文本处理问题:删除其中一列不包含特定值的行

    我有一个制表符分隔的文件 如下所示 input sequence match sequence score receptor group epitope antigen organism ASRPPGGVNEQF ASRPPGGVNEQF
  • shell_exec 的输出被截断为 100 个字符

    当在 shell 中运行以下命令时 curl F file filename http 192 168 0 1 产生以下输出 Accuracy 0 0 1 classification Accuracy 0 0 1 classificati
  • bash 支持字边界正则表达式吗?

    我试图在再次添加该单词之前匹配列表中是否存在该单词 以避免重复 我正在使用 bash 4 2 24 并尝试以下操作 foo bmyword b also foo
  • 使用带有curl 的内部字段分隔符

    当我做 ls IFS l 我得到了我期望的输出 当我做 curl IFShttp www google com 我不 我是否误解了内部字段分隔符 如何在不使用任何空格字符的情况下运行curl 命令 您需要将变量放在大括号内 否则 shell
  • 在 bash 中使用单个命令为 shell 变量分配默认值

    我对 bash 3 00 shell 脚本中的变量进行了大量测试 如果未设置变量 则它会分配默认值 例如 if z VARIABLE then FOO default else FOO VARIABLE fi 我似乎记得有一些语法可以在一行
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • 使用 grep 查找包含所有搜索字符串的行

    我有一个文件 其中包含很多与此类似的行 id 2796 some model Profile message type MODEL SAVE fields account 14 address null modification times
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • 有没有办法让我简化这些回声? [复制]

    这个问题在这里已经有答案了 我仍在学习如何编写 shell 脚本 并且我面临着一个挑战 让我更容易回显 Name1 Name2 Name15 我不太确定从哪里开始 我已经想法 但如果我搞砸了 我不想看起来很傻 有什么帮助吗 我实际上还没有尝
  • 如何在shell中输出返回码?

    我正在尝试通过调用自定义 shell 脚本sh bin sh c myscript sh gt log txt 2 gt 1 echo 该命令的输出是创建的后台进程的 PID 我想指导 bin sh保存返回码myscript sh到某个文件
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • 为什么我可以直接从 bash 执行 JAR?

    我是一个长期从事 Java 工作的人 并且知道运行带有主类的 JAR 的方法MANIFEST MFJar 中的文件很简单 java jar theJar jar 我用它来启动 Fabric3 服务器 包含在bin server jar在其标
  • 使用 su 和 Expect 脚本登录用户时遇到问题

    我正在为一个班级制作一个网站 您可以使用用户名和密码登录 然后它会将您带到一个显示您在班级中的成绩的页面 该网站正在运行bash脚本 https github com jduga002 rapache 并将托管在用户已有用户名和密码登录的计
  • 协助 awk/bash 捕获内存差异

    我正在尝试从以下文件中提取以下输出 xr lab show clock Thu Sep 19 14 38 02 812 WIB 14 38 02 893 WIB Thu Sep 19 2019 xr lab xr lab xr lab sh

随机推荐

  • 如何将 Segment.io 服务器和客户端事件连接到同一匿名用户?

    我正在致力于在现有 NET 电子商务应用程序上实现 Segment 分析中心 以便与 Mixpanel 以及其他一些服务一起使用 我了解 Analytics js 和 Segment NET API 的 API 文档 但我很困惑如何将匿名事
  • 可以在 Google Charts 中生成该 Char 吗?

    我有一个快速的问题 可以在 Google Charts 中生成该 Char 吗 也许你知道该怎么做 有什么建议或什么 Chart1 https i stack imgur com m8tJ3 png 图表下方的白色区域非常重要 这是可能的
  • Spring WS 无效内容类型

    我有一个 Spring WS 客户端 我通过 wsimport 生成了 WSDL 存根 当我尝试发送请求时 收到无效内容类型异常 严重 SAAJ0537 内容类型无效 可能是错误消息而不是 SOAP 消息 线程 main org sprin
  • 使用 Axios 从 http 响应下载 PDF

    我正在开发一个带有 Laravel 后端 API 的 Vue 应用程序 单击链接后 我想调用服务器来下载某个文件 大多数情况下是 PDF 文件 当我做一个get请求与axios我在回复正文中收到了一份 PDF 作为回报 我想直接下载该文件
  • 如何使用 webpack 分别捆绑供应商和主脚本?

    我真的很感谢这里的一些帮助 在这种情况下 我想在最终的构建操作中将我的供应商 js 和我的 main js 分开 我之前尝试过在我的 package json devDependency 中循环分离我的第三方库并将其放入供应商 js 中 它
  • 强制仅从 DataReader 返回单行

    我似乎在我的代码中写了很多这样的内容 using var reader cmd ExecuteReader if reader Read result new User int reader UserId reader UserName T
  • Git 快进 VS 无快进合并

    Git merge 允许我们执行快进和非快进分支合并 有什么想法何时使用快进合并以及何时不使用快进合并吗 The no ff当您想要清楚地了解功能分支时 选项非常有用 因此 即使在此期间没有进行任何提交 FF 也是可能的 有时您仍然希望主线
  • AWS CloudFormation 用户数据中的 Crontab

    使用 AWS CloudFormation Userdata 时如何设置 crontab 我正在设置 crontab l echo 0 wget O q http www example com cron php crontab 但 cro
  • 如何将“=”附加到字符串

    我正在尝试添加 在我的数组的末尾 然后通过附加 0 来结束它 这就是我分配空间的方式 char postExpr malloc sizeof char MAX LEN 我已经尝试了很多方法 但仍然无法在字符串末尾附加字符 其他每个字符都可以
  • QT C++ 的新手问题 - Qimage 不起作用?

    我正在尝试执行控制台应用程序来从图像中读取像素 include
  • R/Shiny 图不显示在浏览器中

    我最近开始玩Shiny 我试图写一些东西来证明中心极限定理 我的代码如下 ui R ui R file code library shiny shinyUI pageWithSidebar headerPanel Central Limit
  • MYSQL 查询左连接显示一张表中的所有数据

    SELECT A CODE B NOTE C NUMBER FROM A LEFT JOIN B ON A CODE B CODE LEFT JOIN C ON A CODE C NUMBER WHERE C ID B ID 需要显示 3
  • Django 1.5.1 运行测试时出现“ImportError:没有名为 urls 的模块”

    我已经开始使用 Django 1 5 项目 我有以下配置文件应用程序的 URL 视图和测试 When I browse localhost 8000 profiles it works just fine 但是当我对配置文件应用程序运行测试
  • 消失 SmartTabLayout pageViewer 内容

    我正在尝试从这里使用 SmartTabLayouthttps github com ogaclejapan SmartTabLayout https github com ogaclejapan SmartTabLayout 我有一个抽屉
  • ASP.NET MVC - Html.TextBox - 未通过 ViewData 字典设置值

    我在页面上有一个带有 Html TextBox 控件的搜索框 实际上是在部分视图中 但不确定是否相关 该操作方法将 query 作为参数 我编辑该值以清理传入的字符串 public ActionResult SearchQuery stri
  • 如何静态链接 C# 类库的库?

    我正在使用 microsoft 提供的 Dlls 在 c 中创建一个类库 现在我想将 Microsoft 提供的库静态添加到 My Dll 中 我该如何执行此操作 我只是添加了对 Microsoft 提供的 Dll 的引用并创建了 My D
  • 包含非 ASCII 字符的批处理文件

    我需要链接到批处理脚本中包含字符 的文件夹 不过 当我运行脚本时 我遇到了麻烦 命令提示符会误读非 ASCII 字符 我尝试将文件保存为 ANSI 和 Unicode 我运行的是 Windows 7 这是一个最小的例子 echo l 没有使
  • Java:如何输出所有可能的二进制组合(256个不同的序列)?

    我需要创建一个函数来输出所有可能的二进制组合 2 8 256 个不同的 8 位序列 我真的很难过这个 我必须使用嵌套循环来完成此操作 并且不知道如何进行 以下是我到目前为止所尝试的 有人告诉我 我可以使用 8 个嵌套循环来编写这个程序 每个
  • 如何在 Google Cloud Functions 上运行 C++ 文件?

    据我所知 Google Cloud Functions 只允许您部署 NodeJs 或 Python 脚本 问题 我怎样才能部署一个简单的Hello World cpp谷歌云功能 例如 编写一个 hello world HTTP 函数 有哪
  • 如何按时间而不是按大小对 shell 脚本输入进行分块?

    在 bash 脚本中 我使用多生产者单消费者模式 生产者是将行写入 fifo 的后台进程 通过 GNU Parallel 消费者从 fifo 读取所有行 然后排序 过滤并将格式化结果打印到 stdout 然而 可能需要很长时间才能获得完整的