私は、カスタムシェルを書いていると私はそれがスクリプトを実行したい:私はbashのから、私のカスタムシェルで実行すると、それが動作カスタムシェル用のシーブン?
if [ type less > /dev/null ];then PAGER=less; fi
echo $PAGER
printenv|grep $1|$PAGER
:
$ ./shell -f ../checkenv.sh GNOME
[13607]
[13606]
GNOME_KEYRING_CONTROL=
GNOME_KEYRING_PID=
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
INSTANCE=GNOME
XDG_CURRENT_DESKTOP=GNOME
(END)
でもあれば、私私のシェルを起動し、スクリプトを実行しようとすると、エラーメッセージが表示されます。
$ ./shell
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin.
$ ../checkenv.sh GNOME
14786: executing ../checkenv.sh
../checkenv.sh: 2: [: type: unexpected operator
14786: executed
$
これは私がシェバングを持っていないためと考えられるが、私は、カスタムシェルのシェバングを使用する方法がわかりません。 /usr/bin/
に私のカスタムシェルをインストールすべきか、それとも別の手配をするべきですか?
私の主な機能と私のreadlineの機能は次のとおりです。
int main(int argc, char *argv[]) {
bool donotrun = false;
struct sigaction new_action, old_action;
hashtable_t *hashtable = ht_create(65536);
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction(SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction(SIGINT, &new_action, NULL);
sigaction(SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction(SIGHUP, &new_action, NULL);
sigaction(SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction(SIGTERM, &new_action, NULL);
bool background = false;
int index = 0;
int i;
char *cvalue = NULL;
const char *commandFile = NULL;
while (1) {
index = 0;
i = getopt_long(argc, argv, "pc:fvh",
options, &index);
if (i == -1)
break;
switch (i) {
case 'p': {
exit(EXIT_SUCCESS);
}
case 'v': {
printf("sh OpenShell version 0.1(a)\n");
printf("Version: %s\n", VERSION);
// printf ("%s/%s/%s/%s\n",
// program_name, version,
// build_date, build_git_sha);
exit(EXIT_SUCCESS);
}
case 'h': {
usage();
exit(EXIT_SUCCESS);
}
case 'c': {
cvalue = optarg;
command(cvalue, hashtable, background);
exit(EXIT_SUCCESS);
}
case 'f': {
/*
* Execute commands from file.
* This is used for osh script files.
* The quiet flag is also set.
*/
//if ((argc != 1) || commandFile)
//usage();
//quietFlag = TRUE;
printf("case f\n");
//commandFile = *argv++;
argc--;
*argv++;
*argv++;
readFile(*argv++, argc, argv, hashtable, background);
//free(line);
exit(0);
//break;
}
case '?':
if (optopt == 'c')
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf(stderr,
"Unknown option character `\\x%x'.\n",
optopt);
default: {
return 1;
}
}
}
getPath();
char *copy = "";
for (; ;) {
bool scanning = true;
while (scanning) {
char *line = NULL;
line = readline("$ ");
if (line == NULL) {
/* No more lines, so exit the loop. */
break;
}
if (line)
copy = strdup(line);
if (line && !strstr(line, "for") && !strstr(line, "==") && !strstr(line, "if") && strstr(line, "=")) {
donotrun = true;
char str[128];
char *ptr;
strcpy(str, line);
strtok_r (str, "=", &ptr);
ht_set(hashtable, str, ptr);
}
if (!scanning)
break;
if (commandFile!=NULL || !isatty(fileno(stdin))) {
*argv++;
readFile(*argv++, argc, argv, hashtable, background);
free(line);
exit(0);
}
else {
if (!donotrun) {
line = strrep(line, " | ", "|");
line = strrep(line, " |", "|");
background = testFn2(line);
if (background)
line[strlen(line) - 1] = '\0';
command(line, hashtable, background);
}
donotrun = false;
add_history(copy);
}
free(copy);
}
}
// ParseFree(pParser, free);FIXME: where should this go?
return 0;
}
/*
* Read commands from the specified file.
* A null name pointer indicates to read from stdin.
*/
static int readFile(const char *name, int argc, char ** argv, hashtable_t *hashtable, bool background) {
FILE *fp;
int cc;
bool ttyFlag;
char buf[CMD_LEN];
int r = 0;
if (sourceCount >= MAX_SOURCE) {
fprintf(stderr, "Too many source files\n");
return 1;
}
fp = stdin;
printf("name %s\n", name);
if (name) {
fp = fopen(name, "r");
if (fp == NULL) {
perror(name);
return 1;
}
}
sourcefiles[sourceCount++] = fp;
ttyFlag = isatty(fileno(fp));
int i = 0;
while (true) {
if (ttyFlag)
showPrompt();
if (intFlag && !ttyFlag && (fp != stdin)) {
fclose(fp);
sourceCount--;
return 1;
}
if (fgets(buf, CMD_LEN - 1, fp) == NULL) {
if (ferror(fp) && (errno == EINTR)) {
clearerr(fp);
continue;
}
break;
}
cc = strlen(buf);
if (buf[cc - 1] == '\n')
cc--;
while ((cc > 0) && isBlank(buf[cc - 1]))
cc--;
buf[cc] = '\0';
//printf("buf %s\n", argv[0]);
strreplace(buf, "$1", argv[0]);
//printf("arg %s\n", ++argv);
if (strstr(buf, "=")) {
char str[128];
char *ptr;
strcpy(str, buf);
strtok_r (str, "=", &ptr);
ht_set(hashtable, str, ptr);
}
//printf("the command is %s\n", buf);
r = command(buf, hashtable, background);
i++;
}
if (ferror(fp)) {
perror("Reading command line");
if (fp == stdin)
exit(1);
}
clearerr(fp);
if (fp != stdin)
fclose(fp);
sourceCount--;
return r;
}
これがCやシェルのソースコードとどのように関係しているかは不明です。 She-bangは実行環境の特徴であり、Cに関連する方法はありません。 – Olaf
'#!/ path/to/my/shell'を試してみてどうしたらいいでしょうか? – a3f
ところで、 '[]'は 'if'構文の一部ではありません。これは、グループ化演算子と同じまたは代替の括弧または中括弧ではありません。文字通り、 '['は 'test'コマンドのエイリアスです。 if [2-gt 1] 'は**あらゆる点で** ** if test 2 -gt 1'と同じです(私が読んだソースは同じ関数で実装されています)あなたのOSは/ usr/bin/['/ usr/bin/test'と同じように' '/ usr/bin/[' 'を提供します(現代のシェルには、 )。 –