- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
<分区>
这些是要求:
这是我的问题:
每当我执行多个命令(使用 command1 | command2)时,我的 shell 在执行给定的命令后终止,而不是在我的 shell 中等待另一个命令行提示符。该程序应该继续运行,并允许用户输入更多命令,直到输入“退出”。
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
// professor-supplied variables for commands and command parsing
char *path, *argv[20], buf[80], n, *p;
int m, status, inword, continu;
// flags for redirection (note: C does not have type bool; using integer value 0 or 1)
int inputRedirectFlag, outputRedirectFlag, backgroundJobFlag;
int numArguments, argIndex, argCount, pipes, openPipesCount, pid, directoryIndex;
// pipes
int p1[2], p2[2];
// index for directory set prior to while(1)
directoryIndex = 0;
while (1) {
inword = 0;
p = buf;
m = 0;
continu = 0;
numArguments = 0;
argIndex = 0;
argCount = 0;
pipes = 0;
openPipesCount = 0;
pid = 0;
// required containers
int argumentContainer[20] = { 0 };
char currentDirectory[80] = { 0 };
// file variables
char *outputFile = (char *)0;
char *inputFile = (char *)0;
// redirection flags
inputRedirectFlag = 0;
outputRedirectFlag = 0;
backgroundJobFlag = 0;
// SHELL PROMPT
printf("\nshhh> ");
// COMMAND PARSING
while ((n = getchar()) != '\n' || continu)
{
/*************************************************
required addition to remediate segmentation fault
*************************************************/
if (n == EOF){
exit(0);
}
if (n == ' ') {
if (inword)
{
inword = 0;
*p++ = 0;
}
}
else if (n == '\n')
continu = 0;
else if (n == '\\' && !inword)
continu = 1;
else {
if (!inword)
{
inword = 1;
argv[m++] = p;
*p++ = n;
}
else
*p++ = n;
}
}
*p++ = 0;
argv[m] = 0;
// capture current working directory
getcwd(currentDirectory, 80);
// user wishes to terminate program
if (strcmp(argv[0], "exit") == 0)
exit(0);
// managing input and output redirection and piping
while (argv[argCount] != 0) {
if (strcmp(argv[argCount], "<") == 0)
{
inputFile = strdup(argv[argCount + 1]);
argv[argCount] = 0;
argv[argCount + 1] = 0;
inputRedirectFlag = 1;
}
else if (strcmp(argv[argCount], ">") == 0)
{
outputFile = strdup(argv[argCount + 1]);
argv[argCount] = 0;
argv[argCount + 1] = 0;
outputRedirectFlag = 1;
}
else if (strcmp(argv[argCount], "&") == 0)
{
argv[argCount] = 0;
backgroundJobFlag = 1;
}
else if (strcmp(argv[argCount], "|") == 0)
{
argv[argCount] = 0;
argumentContainer[pipes + 1] = argCount + 1;
pipes++;
}
else
argumentContainer[argCount] = argCount;
++argCount;
}
// execute commands
for (int i = 0; i <= pipes; ++i) {
// pipe and track piping
if (i < pipes) {
pipe(p1);
++openPipesCount;
}
/*************************************
SWITCH STATEMENT FOR PIPE EXECUTION
*************************************/
/*******************************************************
Using file flags:
O_CREAT: creates file if file does not already exist
O_RDONLY: Access mode for file (read only)
00700(Mode): read/write/execute permission granted
From: http://man7.org/linux/man-pages/man2/open.2.html
********************************************************/
// parent forks child for every exec()
switch (pid = fork()) {
case -1: // process error
perror("fork failed");
break;
case 0: // child process
if ((i == 0) && (inputRedirectFlag == 1)) {
int input = open(inputFile, O_RDONLY | O_CREAT);
if (input == -1) {
printf("Input file failed to open\n");
return(EXIT_FAILURE);
}
close(0);
dup(input);
close(input);
}
else if ((i == pipes) && (outputRedirectFlag == 1)) {
int output = open(outputFile, O_WRONLY | O_CREAT, 00700);
if (output < 0) {
printf("Output file failed to open\n");
return(EXIT_FAILURE);
}
close(1);
dup(output);
close(output);
}
// EXECUTE COMMAND
execvp(argv[argumentContainer[argIndex]], &argv[argumentContainer[argIndex]]);
break;
default: // parent process
if (openPipesCount > 0) {
close(p2[0]);
close(p2[1]);
}
p2[0] = p1[0];
p2[1] = p1[1];
break;
}
/*************************************
END SWITCH STATEMENT FOR PIPE EXECUTION
*************************************/
// if job is not a run-in-background process, wait for process to complete
if (backgroundJobFlag == 0)
wait((int *)0);
}
// user wishes to terminate program
if (strcmp(argv[0], "exit") == 0)
exit(0);
// clear all executed commands
for (int i = 0; i < 20; ++i)
argv[i] = 0;
wait(&status);
}
}
第一次更新/更改。多个命令正在运行,但现在我的文件重定向(用于输入)不起作用,还有其他问题:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
//#include <sys/stat.h>
#include <fcntl.h>
#ifndef READ
#define READ 0
#endif
#ifndef WRITE
#define WRITE 1
#endif
int main() {
// professor-supplied variables for commands and command parsing
char *path, *argv[20], buf[80], n, *p;
int m, status, inword, continu;
int inputRedirectFlag, outputRedirectFlag, backgroundJobFlag;
int numArguments, argIndex, argCount, activeCommands, openPipesCount;
pid_t pid;
int directoryIndex, commandArchiveIndex;
int oldFileDescriptor[2], newFileDescriptor[2];
directoryIndex = 0;
while (1) {
inword = 0;
p = buf;
m = 0;
continu = 0;
numArguments = 0;
argIndex = 0;
argCount = 0;
activeCommands = 0;
openPipesCount = 0;
pid = 0;
path = (char*)0;
// required containers
int argumentContainer[20] = { 0 };
char currentDirectory[80] = { 0 };
// archive of all commands
char *commandArchive[20] = { 0 };
// redirection flags
inputRedirectFlag = 0;
outputRedirectFlag = 0;
backgroundJobFlag = 0;
// SHELL PROMPT
printf("\nshhh> ");
// COMMAND PARSING
while ((n = getchar()) != '\n' || continu)
{
if (n == ' ') {
if (inword)
{
inword = 0;
*p++ = 0;
}
}
else if (n == '\n')
continu = 0;
else if (n == '\\' && !inword)
continu = 1;
else {
if (!inword)
{
inword = 1;
argv[m++] = p;
*p++ = n;
}
else
*p++ = n;
}
}
*p++ = 0;
argv[m] = 0;
// capture all commands in command archive
while (argv[argIndex] != 0)
{
commandArchive[numArguments] = strdup(argv[argIndex]);
numArguments++;
++argIndex;
}
// capture current working directory
getcwd(currentDirectory, 80);
// user wishes to terminate program
if (strcmp(argv[0], "exit") == 0)
exit(0);
/*************************
MANAGE BUILT-IN FUNCTIONS
**************************/
// user command is "cd"
if (strcmp(argv[0], "cd") == 0) {
if (strcmp(argv[1], ".") == 0){ // this should do nothing as a command
// *path = ???
break;
}
else if (strcmp(argv[1], "..") == 0) { // this should move user up one directory
// *path = ???
// NEED TO PASS PATH HERE!
chdir(currentDirectory);
}
else {
while (argv[directoryIndex] != 0) {
getcwd(currentDirectory, 80);
// *path = ???
// NEED TO PASS PATH HERE!
chdir(argv[directoryIndex]);
++directoryIndex;
}
}
}
/********************************************
MANAGE REDIRECTION AND BACKGROUND PROCESSING
********************************************/
while (argv[argCount] != 0) {
if (strcmp(argv[argCount], "|") == 0) {
argv[argCount] = 0;
argumentContainer[activeCommands + 1] = argCount + 1;
++activeCommands;
}
else if (strcmp(argv[argCount], "<") == 0) {
path = strdup(argv[argCount + 1]);
argv[argCount] = 0;
argv[argCount + 1] = 0;
inputRedirectFlag = 1;
}
else if (strcmp(argv[argCount], ">") == 0) {
path = strdup(argv[argCount + 1]);
argv[argCount] = 0;
argv[argCount + 1] = 0;
outputRedirectFlag = 1;
}
else if (strcmp(argv[argCount], "&") == 0) {
argv[argCount] = 0;
backgroundJobFlag = 1;
}
else {
argumentContainer[argCount] = argCount;
}
++argCount;
}
// execute commands
for (int pipeIndex = 0; pipeIndex <= activeCommands; ++pipeIndex) {
if (pipeIndex < activeCommands) { // if user has entered multiple commands with '|'
pipe(oldFileDescriptor);
pipe(newFileDescriptor);
++openPipesCount;
}
/*************************************
SWITCH STATEMENT FOR PIPE EXECUTION
*************************************/
// capture current path
//path = getenv("PATH");
/*******************************************************
Using file flags:
O_CREAT: creates file if file does not already exist
O_RDONLY: Access mode for file (read only)
0600(Mode): owner can read/write
ddddddddddddd
********************************************************/
// parent forks child for every exec()
switch (pid = fork()) {
case -1: // process error
perror("fork failed");
break;
case 0: // child process
/****************************************************
HAVE CHILD PROCESS MANAGE REDIRECTION
****************************************************/
if ((pipeIndex == 0) && (inputRedirectFlag == 1)) {
int input = open(path, O_RDONLY | O_CREAT, 0600);
if (input == -1) {
printf("Input file failed to open\n");
return(EXIT_FAILURE);
}
//close(READ);
//dup(input);
//close(input);
dup2(input, READ);
close(input);
}
else if ((pipeIndex == activeCommands) && (outputRedirectFlag == 1)) {
int output = open(path, O_WRONLY | O_CREAT, 0600);
if (output < 0) {
printf("Output file failed to open\n");
return(EXIT_FAILURE);
}
//close(WRITE);
//dup(output);
//close(output);
dup2(output, WRITE);
close(output);
}
/****************************************************
REDIRECTION (IF APPLICABLE) EXECUTED BY CHILD PROCESS
****************************************************/
/*******************************************************************************
CHILD EXECUTES COMMAND:
*******************************************************************************/
execvp(argv[argumentContainer[pipeIndex]], &argv[argumentContainer[pipeIndex]]);
/*******************************************************************************
EXECUTION COMPLETE
*******************************************************************************/
break;
default: // parent process
if (openPipesCount > 0) { // previous command
//close(READ);
//dup(newFileDescriptor[READ]);
close(newFileDescriptor[READ]);
close(newFileDescriptor[WRITE]);
}
if (openPipesCount < activeCommands) { // more commands need to be executed
close(newFileDescriptor[READ]);
dup(newFileDescriptor[WRITE]);
close(newFileDescriptor[WRITE]);
}
oldFileDescriptor[READ] = newFileDescriptor[READ];
oldFileDescriptor[WRITE] = newFileDescriptor[WRITE];
break;
}
/***************************************
END SWITCH STATEMENT FOR PIPE EXECUTION
**************************************/
// if job is not a run-in-background process, wait for process to complete
if (backgroundJobFlag == 0)
wait((int *)0);
}
// user wishes to terminate program
if (strcmp(argv[0], "exit") == 0)
exit(0);
// clear all executed commands
for (int i = 0; i < 20; ++i)
argv[i] = 0;
wait(&status);
}
}
我知道我可能在 argumentContainer[] 或管道方面做错了什么。我只是迷路了。
更新版本(更新 2):
在与我的教授讨论我的代码后,我做了很多更改。它几乎工作。我能够通过管道传输多个命令等。但是,“wc”似乎卡住并等待 EOF (ctrl+d),并且 cd 没有更改目录。想知道我是否需要为“cd”制作一个特例/代码。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef READ
#define READ 0
#endif
#ifndef WRITE
#define WRITE 1
#endif
int main() {
/* professor-supplied variables for commands and command parsing */
char *path, *argv[20], buf[80], n, *p;
int m, status, inword, continu;
/* flags for redirection (note: C does not have type bool; using integer value 0 or 1) */
int inputRedirectFlag, outputRedirectFlag;
/* variables for piping */
int count, pipes;
pid_t pid;
/* pipes */
int l_pipe[2], r_pipe[2];
while (1) {
inword = m = continu = count = pipes = pid = 0;
p = buf;
/* required container for handling arguments */
int argumentContainer[20] = { 0 };
/* redirection flags */
inputRedirectFlag = 0;
outputRedirectFlag = 0;
/* shell prompt */
printf("\nshhh> ");
/* command parsing */
while ((n = getchar()) != '\n' || continu)
{
if (n == ' ') {
if (inword)
{
inword = 0;
*p++ = 0;
}
}
else if (n == '\n')
continu = 0;
else if (n == '\\' && !inword)
continu = 1;
else {
if (!inword)
{
inword = 1;
argv[m++] = p;
*p++ = n;
}
else
*p++ = n;
}
} /* end of command parsing */
*p++ = 0;
argv[m] = 0;
/* user wishes to terminate program */
if (strcmp(argv[0], "exit") == 0)
exit(0);
/* manage redirection */
while (argv[count] != 0) {
if (strcmp(argv[count], "|") == 0) {
argv[count] = 0;
argumentContainer[pipes + 1] = count + 1;
++pipes;
}
else if (strcmp(argv[count], "<") == 0) {
path = strdup(argv[count + 1]); /* copy string argument (file string) */
argv[count] = 0;
argv[count + 1] = 0;
inputRedirectFlag = 1;
}
else if (strcmp(argv[count], ">") == 0) {
path = strdup(argv[count + 1]); /* copy string argument (file string) */
argv[count] = 0;
argv[count + 1] = 0;
outputRedirectFlag = 1;
}
else {
argumentContainer[count] = count;
}
++count;
} /* end of redirection management */
/* execute commands */
for (int index = 0; index <= pipes; ++index) {
if (index < pipes) { /* if user has entered multiple commands with '|' */
pipe(r_pipe); /* no pipe(l_pipe); r_pipe becomes next child's l_pipe */
}
/*************************************************************************
FILE FLAG AND FILE MODE DESCRIPTION AND DETAILS:
*************************************************************************
Using file flags:
O_CREAT: creates file if file does not already exist
O_REDONLY: Acess mode for file (read only)
O_WRONLY: Access mode for file (write only)
0600(Mode): owner can read/write
From:
http://www.thinkplexx.com/learn/article/unix/command
************************************************************************
***********************************************************************/
/* switch-statement for command execution */
switch (pid = fork()) {
/* fork() error */
case -1: perror("fork failed");
break;
case 0: /* child process manages redirection and executes */
if ((index == 0) && (inputRedirectFlag == 1)) {
int input = open(path, O_RDONLY , 0600);
if (input == -1) {
printf("Input file failed to open\n");
return(EXIT_FAILURE);
}
dup2(input, READ);
close(input);
} /* end of input redirection management */
else if ((index == pipes) && (outputRedirectFlag == 1)) {
int output = open(path, O_WRONLY | O_CREAT, 0600);
if (output < 0) {
printf("Output file failed to open\n");
return(EXIT_FAILURE);
}
dup2(output, WRITE);
close(output);
} /* end of output redirection management */
/* command executed */
execvp(argv[argumentContainer[index]], &argv[argumentContainer[index]]);
/* execvp() fails */
printf("execution of command failed\n");
break;
default: /* parent process manages the pipes for child process(es) */
if (index > 0) {
close(l_pipe[READ]);
close(l_pipe[WRITE]);
}
l_pipe[READ] = r_pipe[READ];
l_pipe[WRITE] = r_pipe[WRITE];
break;
} /* end of switch-statement for command execution */
} /* end of loop for all pipes */
// user wishes to terminate program
if (strcmp(argv[0], "exit") == 0) {
exit(0);
}
// clear all executed commands
for (int i = 0; i < 20; ++i) {
argv[i] = 0;
}
wait(&status);
}
}
我相信我在子 shell 中调用 exit 会导致我的程序继续: #!/bin/bash grep str file | while read line do exit 0 done
我相信我在子 shell 中调用 exit 会导致我的程序继续: #!/bin/bash grep str file | while read line do exit 0 done
我有几个脚本,它们的第一部分看起来是一样的。这部分的功能是识别脚本在哪台机器上运行并相应地设置几个变量。它看起来像这样: ENV=`echo $LOGNAME | cut -c1-8` if
这是我正在尝试做的事情。我有 4 个 shell 脚本。脚本 1 需要先运行,然后是 2,然后是 3,然后是 4,并且它们必须按此顺序运行。脚本 1 需要运行(并在后台等待)2 才能正常运行,但是脚本
我有一个名为 a.sh 的脚本,其中的内容是: //a.sh: #!/bin/bash temp=0 while [ "$temp" -ne 500 ] do echo `date`
在snakemake中,使用shell()函数执行多个命令的推荐方式是什么? 最佳答案 您可以调用shell()多次内run规则块(规则可以指定 run: 而不是 shell: ): rule pro
我有一个 shell 脚本,我向其中传递了一些参数。Test1.sh -a 1 -b 2 -c“一二三” 在 Test1.sh 中,我按以下方式调用另一个 shell 脚本。Test2.sh $* 我
我有 2 个 shell 脚本。 第二个shell脚本包含以下函数第二个.sh func1 func2 first.sh 将使用一些参数调用第二个 shell 脚本, 将使用特定于该函数的一些其他参数
我有一个 Unix shell 脚本 test.sh。在脚本中,我想调用另一个 shell,然后从子 shell 执行 shell 脚本中的其余命令并退出 说清楚: test.sh #! /bin/b
我想在 shell 脚本中更改路径环境变量。路径变量需要在shell脚本执行后修改。 最佳答案 我知道有两种方法可以做到这一点。第一种是在当前 shell 的上下文中运行脚本: . myscript.
此 shell 脚本按预期运行。 trap 'echo exit' EXIT foo() { exit } echo begin foo echo end 这是输出。 $ sh foo.sh
我正在使用 vimshell在 vim 中执行命令 nnoremap vs :VimShellPop 使用此键映射,我可以打开 vim shell 并执行诸如“捆绑安装”之类的命令,然后 输入 exi
我想连接到不同的 shell(csh、ksh 等)并在每个切换的 shell 中执行命令。 下面是反射(reflect)我的意图的示例程序: #!/bin/bash echo $SHELL csh e
我目前正在尝试使用 BNF 和 LL 解析器在 C 中重新编写 shell。 否则,我需要知道 shell 运算符的优先级是什么| , > , > , & , ; ? 有没有人可以提供给我? 谢谢 最
不幸的是,我没有suspend 命令(busybox/ash)。但是我可以使用 kill -STOP $$ 从后台 shell (sh &) 返回到父 shell(以及 fg 之后)。 但是我不想输入
我需要知道,当用户切换到另一个 shell 时,通过单击它。 我试过 shellListener.shellDeactivated()但是当 shell 失去对它自己的控件的焦点时,会触发此事件,这意
file1.txt aaaa bbbb cccc dddd eeee file2.txt DDDD cccc aaaa 结果 bbbb eeee 如果能不区分大小写就更好了! 谢谢! 最佳答案 gre
我见过解压缩目录中所有 zip 文件的循环。但是,在运行此之前,我宁愿确保我将要运行的内容正常工作: for i in dir; do cd $i; unzip '*.zip'; rm -rf *.z
我对编程还很陌生,但我想知道 vim、emacs、nano 等 shell 文本编辑器如何能够控制命令行窗口。我主要是一名 Windows 程序员,所以可能在 *nix 上有所不同。据我所知,只能将文
我有一个包含第 7 列日期的文件,我的要求是将它与今天的日期进行比较,如果小于它,则删除该完整行。 此外,如果第 7 列中提到的任何日期超过 15 天,则将其修改为最多 15 天 下面的例子- now
我是一名优秀的程序员,十分优秀!