2

I am trying to run a Bash command where an alias exists in PowerShell Core.

I want to clear the bash history. Example code below:

# Launch PowerShell core on Linux
pwsh

# Attempt 1
history -c
Get-History: Missing an argument for parameter 'Count'. Specify a parameter of type 'System.Int32' and try again.

# Attempt 2
bash history -c
/usr/bin/bash: history: No such file or directory

# Attempt 3
& "history -c"
&: The term 'history -c' is not recognized as the name of a cmdlet, function, script file, or operable program.

It seems the issue is related to history being an alias for Get-History - is there a way to run Bash commands in PowerShell core with an alias?

2
  • 1
    I think you want bash -c history -c Commented Sep 7, 2021 at 16:30
  • 1
    @briantist, our wires had crossed in answering (you were first); syntactically, it would have to be bash -c 'history -c' (single -c argument), but with this particular command it doesn't actually work. I've also added some more info about Bash's CLI to the answer. Commented Sep 7, 2021 at 17:25

1 Answer 1

3
  • history is a Bash builtin, i.e. an internal command that can only be invoked from inside a Bash session; thus, by definition you cannot invoke it directly from PowerShell.

  • In PowerShell history is an alias of PowerShell's own Get-History cmdlet, where -c references the -Count parameter, which requires an argument (the number of history entries to retrieve).

    • Unfortunately, Clear-History is not enough to clear PowerShell's session history as of PowerShell 7.2, because it only clear's one history (PowerShell's own), not also the one provided by the PSReadLine module used for command-line editing by default - see this answer.

Your attempt to call bash explicitly with your command - bash history -c - is syntactically flawed (see bottom section).

However, even fixing the syntax problem - bash -c 'history -c' - does not clear Bash's history - it seemingly has no effect (and adding the -i option doesn't help) - I don't know why.

The workaround is to remove the file that underlies Bash's (persisted) command history directly:

if (Test-Path $HOME\.bash_history) { Remove-Item -Force $HOME\.bash_history }

To answer the general question implied by the post's title:

To pass a command with arguments to bash for execution, pass it to bash -c, as a single string; e.g.:

bash -c 'date +%s'

Without -c, the first argument would be interpreted as the name or path of a script file.

Note that any additional arguments following the first -c argument would become the arguments to the first argument; that is, the first argument acts as a mini-script that can receive arguments the way scripts usually do, via $1, ...:

# Note: the second argument, "-", becomes $0 in Bash terms,
#       i.e. the name of the script
PS> bash -c 'echo $0; echo arg count: $#' self one two
self
arg count: 2
Sign up to request clarification or add additional context in comments.

2 Comments

As you noted, bash -c ‘history -c’ does not work. Also, creating env variables using bash -c ‘export test=123’ has no effect. Any idea why that is? Can’t find alternatives online.
@user9924807, any external program you run from PowerShell (or any shell, for that matter) of necessity runs in a child process. Therefore, any environment variable you set in that chid process is limited to that child process (and any of its children) - PowerShell never see it. If you want to set an environment variable for the current PowerShell session, use $env:test = '123'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.