1

One may want to use Bash on Windows in Task Scheduler or maybe as version-control hook scripts. Is it possible or supported?

If not, why? Is it a bug or a measure to prevent some issues?

bahrep
  • 29,961
  • 12
  • 103
  • 150
  • 2
    Do not vote to close just because you do not know the answer. If you think that I am asking for a software recommendation, re-read the question. PS I know the first part of the answer, but I want to give others an opportunity to look into that issue. Nether the question, nor the answer can be considered as "too broad". Thanks. – bahrep Aug 30 '17 at 13:32
  • Are you there? Did my answer answer your question? – 3D1T0R Oct 09 '17 at 18:55
  • @3D1T0R I am here. The answer is not correct. – bahrep Oct 09 '17 at 18:56
  • What's wrong with it? `bash -c "insert Linux command here"` works for me. Can you be more specific about what exactly you're trying to do and how it's not working for you? – 3D1T0R Oct 09 '17 at 19:15
  • @3D1T0R the question is about WSL (Windows Subsystem for Linux). It does not support non interactive sessions. – bahrep Oct 09 '17 at 19:24
  • I personally use WSL in exactly the manner described in my answer on a daily basis. Please try it before you say it's wrong. – 3D1T0R Oct 10 '17 at 01:49

2 Answers2

1

Use @3d1t0r's solution, but also pipe to cat

wsl bash -c "man bash | cat"  # noninteractive; streams the entire manpage to the terminal
wsl bash -c "man bash"        # shows me the first page, and lets me scroll around; need to hit `q` to exit

If interactive mode is fine, bash -c is often superfluous

wsl man bash                  # same behavior as `wsl bash -c "man bash"`

Context (what in the world is "interactive" vs "non-interactive" invocation?):

The example above might not make it entirely clear, but man is changing its behavior based on what it's connected to.

  • In "interactive mode", man lets me scroll around, so that I can read the page at a comfortable reading pace.
  • In noninteractive mode, man dumps the entire manpage to the console, giving me no time to read anything.

"But wait," I hear you ask, "isn't man catting the man page because you asked it to? I see it right there--man bash | cat"

No, man has no idea what cat is. It just gets hints about whether STDOUT is connected to an interactive terminal.

Here's a different example, that consistently cats:

wsl bash -c "echo hey | grep --color e"       # colors 'e' red
wsl bash -c "echo hey | grep --color e | cat" # colors disappear, what gives?

Now both examples are streaming their output, but the second one is defiantly ignoring my --color flag.

The common thread here is man and grep both behave appropriately depending on whether they think their output is going to be read by a human piped away somewhere.

Other common commands that auto-detect interactivity include ls and git. Usually the behavior change will involve output paging or colors (other variations exist).

  • paging is nice for humans, because humans generally can't read at the speed of streamed output.
  • paging is bad for robots, because paging is a lot of protocol overhead when you can just consume buffered streams. I mean seriously, why are humans so slow and chatty?
  • colors are nice for humans, because we like additional visual cues to aid visual distinction.
  • colors are bad for streaming to file, because your file will be full of ansi color code garbage, that most text editors don't display nicely.

Automatic behavior switching based on whether STDOUT is connected to an interactive terminal makes all these use cases usually "just work".

Restating the Original Question

In my use case and @bahrep's use case, interactive mode can be especially bad for unsupervised scripts (e.g. as launched by Task Scheduler). I am guessing @bahrep's scheduled runs hung on less getting invoked and waiting for human input.

For some reason, wsl-driven scripts launched from the task-scheduler give underlying scripts the wrong hints--they hint that the final output is attached to an interactive terminal.

Ideally, wsl would know from the windows side of the execution environment whether it is getting invoked interactively or not, and pass along the proper hint. Then I could just run wsl [command]. Until that happens, I'll need to use wsl bash -c "[command] | cat" as a workaround.

nar8789
  • 727
  • 6
  • 9
0

If I'm understanding your question correctly, the -c option is what you're looking for. It allows you to directly invoke a Linux command.
For example, to open the man page for bash (perhaps in order to find out about the -c option):

bash -c "man bash"

Note: You can leave off the quotes if you escape any spaces (e.g. bash -c man\ bash), but it's often easier to just use the quotes, as the first unescaped space will lose the rest of your command.
e.g. bash -c man bash will be interpreted the same as bash -c man.

3D1T0R
  • 1,050
  • 7
  • 17