mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-12 13:08:49 +00:00
parent
f52708a20f
commit
4fde67fa50
6 changed files with 122 additions and 0 deletions
|
@ -1,5 +1,11 @@
|
||||||
# fish 2.6.0 (released ???)
|
# fish 2.6.0 (released ???)
|
||||||
|
|
||||||
|
## Notable fixes and improvements
|
||||||
|
|
||||||
|
- Jobs running in the background can now be removed from the list of jobs with the new `disown` builtin, which behaves like the same command in other shells (#2810).
|
||||||
|
|
||||||
|
## Other significant changes
|
||||||
|
|
||||||
- The `export` and `setenv` commands now supports colon-separated `PATH`, `CDPATH` and `MANPATH`.
|
- The `export` and `setenv` commands now supports colon-separated `PATH`, `CDPATH` and `MANPATH`.
|
||||||
- The `read` command now has a default limit of 10 MiB. If a line is longer than that it will fail with $status set to 122 and the var will be empty. You can set a different limit by setting the FISH_READ_BYTE_LIMIT variable.
|
- The `read` command now has a default limit of 10 MiB. If a line is longer than that it will fail with $status set to 122 and the var will be empty. You can set a different limit by setting the FISH_READ_BYTE_LIMIT variable.
|
||||||
- `read` now supports the `--silent` flag to hide the characters typed (#838).
|
- `read` now supports the `--silent` flag to hide the characters typed (#838).
|
||||||
|
|
26
doc_src/disown.txt
Normal file
26
doc_src/disown.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
\section disown disown - remove a process from the list of jobs
|
||||||
|
|
||||||
|
\subsection disown-synopsis Synopsis
|
||||||
|
\fish{synopsis}
|
||||||
|
disown [ PID ... ]
|
||||||
|
\endfish
|
||||||
|
|
||||||
|
\subsection disown-description Description
|
||||||
|
|
||||||
|
`disown` removes the specified <a href="index.html#syntax-job-control">job</a> from the list of jobs. The job itself continues to exist, but fish does not keep track of it any longer.
|
||||||
|
|
||||||
|
Jobs in the list of jobs are sent a hang-up signal when fish terminates, which usually causes the job to terminate; `disown` allows these processes to continue regardless.
|
||||||
|
|
||||||
|
If no process is specified, the most recently-used job is removed (like `bg` and `fg`). If one or more `PID`s are specified, jobs with the specified process IDs are removed from the job list. Invalid jobs are ignored and a warning is printed.
|
||||||
|
|
||||||
|
If a job is stopped, it is sent a signal to continue running, and a warning is printed. It is not possible to use the `bg` builtin to continue a job once it has been disowned.
|
||||||
|
|
||||||
|
The PID of the desired process is usually found by using <a href="index.html#expand-process">process expansion</a>, which can specify jobs or search by process name.
|
||||||
|
|
||||||
|
`disown` returns 0 if all specified jobs were disowned successfully, and 1 if any problems were encountered.
|
||||||
|
|
||||||
|
\subsection disown-example Example
|
||||||
|
|
||||||
|
`firefox &; disown` will start the Firefox web browser in the background and remove it from the job list, meaning it will not be closed when the fish process is closed.
|
||||||
|
|
||||||
|
`disown (jobs -p)` removes all jobs from the job list without terminating them.
|
|
@ -3058,6 +3058,86 @@ static int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper for builtin_disown
|
||||||
|
static int disown_job(parser_t &parser, io_streams_t &streams, job_t *j) {
|
||||||
|
if (j == 0) {
|
||||||
|
streams.err.append_format(_(L"%ls: Unknown job '%ls'\n"), L"bg");
|
||||||
|
builtin_print_help(parser, streams, L"disown", streams.err);
|
||||||
|
return STATUS_BUILTIN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stopped disowned jobs must be manually signalled; explain how to do so
|
||||||
|
if (job_is_stopped(j)) {
|
||||||
|
killpg(j->pgid, SIGCONT);
|
||||||
|
streams.err.append_format(
|
||||||
|
_(L"%ls: job %d ('%ls') was stopped and has been signalled to continue.\n"),
|
||||||
|
L"disown", j->job_id, j->command_wcstr());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser.job_remove(j)) {
|
||||||
|
return STATUS_BUILTIN_OK;
|
||||||
|
} else {
|
||||||
|
return STATUS_BUILTIN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builtin for removing jobs from the job list
|
||||||
|
static int builtin_disown(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
|
int res = STATUS_BUILTIN_OK;
|
||||||
|
|
||||||
|
if (argv[1] == 0) {
|
||||||
|
job_t *j;
|
||||||
|
// Select last constructed job (ie first job in the job queue) that is possible to disown.
|
||||||
|
// Stopped jobs can be disowned (they will be continued).
|
||||||
|
// Foreground jobs can be disowned.
|
||||||
|
// Even jobs that aren't under job control can be disowned!
|
||||||
|
job_iterator_t jobs;
|
||||||
|
while ((j = jobs.next())) {
|
||||||
|
if (j->get_flag(JOB_CONSTRUCTED) && (!job_is_completed(j))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j) {
|
||||||
|
res = disown_job(parser, streams, j);
|
||||||
|
} else {
|
||||||
|
streams.err.append_format(_(L"%ls: There are no suitable jobs\n"), argv[0]);
|
||||||
|
res = STATUS_BUILTIN_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::set<job_t *> jobs;
|
||||||
|
|
||||||
|
// If one argument is not a valid pid (i.e. integer >= 0), fail without disowning anything,
|
||||||
|
// but still print errors for all of them.
|
||||||
|
// Non-existent jobs aren't an error, but information about them is useful.
|
||||||
|
// Multiple PIDs may refer to the same job; include the job only once by using a set.
|
||||||
|
for (int i = 1; argv[i]; i++) {
|
||||||
|
int pid = fish_wcstoi(argv[i]);
|
||||||
|
if (errno || pid < 0) {
|
||||||
|
streams.err.append_format(_(L"%ls: '%ls' is not a valid job specifier\n"), argv[0],
|
||||||
|
argv[i]);
|
||||||
|
res = STATUS_BUILTIN_ERROR;
|
||||||
|
} else {
|
||||||
|
if (job_t *j = parser.job_get_from_pid(pid)) {
|
||||||
|
jobs.insert(j);
|
||||||
|
} else {
|
||||||
|
streams.err.append_format(_(L"%ls: Could not find job '%d'\n"), argv[0], pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res == STATUS_BUILTIN_ERROR) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disown all target jobs
|
||||||
|
for (auto j : jobs) {
|
||||||
|
res |= disown_job(parser, streams, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/// This function handles both the 'continue' and the 'break' builtins that are used for loop
|
/// This function handles both the 'continue' and the 'break' builtins that are used for loop
|
||||||
/// control.
|
/// control.
|
||||||
static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
static int builtin_break_continue(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
|
@ -3542,6 +3622,7 @@ static const builtin_data_t builtin_datas[] = {
|
||||||
{L"continue", &builtin_break_continue,
|
{L"continue", &builtin_break_continue,
|
||||||
N_(L"Skip the rest of the current lap of the innermost loop")},
|
N_(L"Skip the rest of the current lap of the innermost loop")},
|
||||||
{L"count", &builtin_count, N_(L"Count the number of arguments")},
|
{L"count", &builtin_count, N_(L"Count the number of arguments")},
|
||||||
|
{L"disown", &builtin_disown, N_(L"Remove job from job list")},
|
||||||
{L"echo", &builtin_echo, N_(L"Print arguments")},
|
{L"echo", &builtin_echo, N_(L"Print arguments")},
|
||||||
{L"else", &builtin_generic, N_(L"Evaluate block if condition is false")},
|
{L"else", &builtin_generic, N_(L"Evaluate block if condition is false")},
|
||||||
{L"emit", &builtin_emit, N_(L"Emit an event")},
|
{L"emit", &builtin_emit, N_(L"Emit an event")},
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
bg: '-23' is not a valid job specifier
|
bg: '-23' is not a valid job specifier
|
||||||
fg: No suitable job: 3
|
fg: No suitable job: 3
|
||||||
bg: Could not find job '3'
|
bg: Could not find job '3'
|
||||||
|
disown: 'foo' is not a valid job specifier
|
||||||
|
|
|
@ -4,4 +4,9 @@ jobs -c
|
||||||
bg -23 1
|
bg -23 1
|
||||||
fg 3
|
fg 3
|
||||||
bg 3
|
bg 3
|
||||||
|
sleep 1 &
|
||||||
|
disown
|
||||||
|
jobs -c
|
||||||
|
disown foo
|
||||||
|
disown (jobs -p)
|
||||||
or exit 0
|
or exit 0
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
Command
|
Command
|
||||||
sleep
|
sleep
|
||||||
sleep
|
sleep
|
||||||
|
Command
|
||||||
|
sleep
|
||||||
|
sleep
|
||||||
|
|
Loading…
Reference in a new issue