22

I have a windows program running on Linux using WINE.

How can I call Linux shell commands from the windows program?

UKnoHowWeDo
  • 343
  • 1
  • 2
  • 6

10 Answers10

13

With newer Wine versions (tested with Wine 1.7.38), you can run a Linux program from within Wine in the following way (here to launch gedit, as an example):

wineconsole cmd

...and from that wine console:

start /unix /usr/bin/gedit

If you want to launch a Linux program directly from within a Windows-application, the following line did work for me:

cmd /c start /unix /usr/bin/gedit

To test this, you can call directly on your Linux console this:

wine cmd /c start /unix /usr/bin/gedit

One important thing to Note: the program you want to start needs to have the executable bit set, otherwise calling it from Wine will fail!

adrianer
  • 131
  • 1
  • 4
  • 5
    This works for ui applications, but I can't seem to get it to work with any command-line ones - i.e. ffmpeg, git, etc. It doesn't show an error, nor any output. Just nothing. Has anyone else had any luck? – J23 Jun 27 '20 at 07:48
10

Try this (runs Gnome calculator on my Linux Mint system):

wineconsole cmd

...and from the wine console:

/bin/sh gcalctool

On this general principle, you can also open documents and associate files with a linux app by editing the wine registry. There is a section about it in the wine FAQ:

6.6.3 How do I associate a native program with a file type in Wine?

So you should be able to write shell scripts and call them OK.

GKFX
  • 1,386
  • 1
  • 11
  • 30
Psen
  • 109
  • 1
  • 3
4

How to call a Linux program from a Wine program — five points in terms of API.

1. Proper PATHEXT

In the new Wine versions (since 2.0.1 at least) it is need to add empty extension (i.e. just dot character: .) into the list of executable file extensions in PATHEXT environment variable. Without this addition an error message can say something like:

Can't recognize '/bin/bash' as an internal or external command, or batch script.

To fix the initial PATHEXT value in the registry the following commands snippet can be used (for each WINEPREFIX):

k='HKLM\System\CurrentControlSet\Control\Session Manager\Environment'
pathext_orig=$( wine reg query "$k" /v PATHEXT | tr -d '\r' | awk '/^  /{ print $3 }' )
echo "$pathext_orig" | grep -qE '(^|;)\.(;|$)' \
  || wine reg add "$k" /v PATHEXT /f /d "${pathext_orig};."

This code checks and then modifies PATHEXT if it doesn't contain . item only.

See also: How do I launch native applications from a Windows application? in WineHQ FAQ; NB:

Note that this change will have to be made every time you upgrade Wine, as it will be reverted whenever the wineprefix is updated.

2. Path to executable

It is likely that by default you will need to specify the full (or relative) path to an executable file (for example, /bin/bash), since a Wine process doesn't inherit PATH environment variable from the parent Linux process. Note that the current drive in a Wine process is mapped to the Linux root folder by default, so no need to specify a drive letter. I.e. /bin/bash just works, but not bash.

Another way is to alter PATH environment variable in Wine accordingly, or to change the current directory.

Whenever a path contains non-ASCII characters — as argument of CreateProcessA — the path should be in Wine locale and according to LANG environment variable; see also the answer by Eugene in this topic, and a forum post how to set encoding to use with non-Unicode application in Wine. For CreateProcessW the path should be in UTF-16 in any case.

3. Executable format

Linux executables in shared object format cannot be executed from Wine. See: Executables vs Shared objects and How to execute shell scripts from 32-bit Wine on 64-bit Linux. For example, /bin/dash can be "ELF 64-bit LSB shared object" (see output of file /bin/dash) and cannot be executed from Wine in such case. Error message says:

wine: Bad EXE format for Z:\bin\dash..
Can't recognize '/bin/dash' as an internal or external command, or batch script.

4. No waiting

A parent Wine process cannot wait (for example, via WaitForSingleObject) on a child Linux process since it isn't provided with the child process handle — it is just 0. See bugreport: CreateProcess doesn't set hProcess correctly when starting a Linux program (Status: CLOSED WONTFIX).

Nevertheless a parent process can indirectly wait a child process via blocking read on the certain pipe if the child process uses stdout (see also bellow).

5. Difference in pipes redirection

Perhaps it is a bug in Wine, but a parent process should close the std handles, that are passed into CreateProcess, only after close the own handles (or just before it) for the corresponding pipes. While in Windows these handles can be closed just after CreateProcess function is completed. By MSDN these handles may be closed at once after passing (see CreateProcess function):

Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.

In Wine 2.0.1, the corresponding pipe in a child Linux process will be closed immediately in such case, and the child process will prematurely stop. But not in the case of a child Windows process.

ruvim
  • 7,151
  • 2
  • 27
  • 36
  • 1
    I haven't been able to get any command-line Linux applications to run from Wine (i.e. ffmpeg, git, etc) - it doesn't show an error, nor any output. Just nothing. I'm guessing this might be related to your 5th point: the pipe in a child Linux process will be closed immediately, and the child process will prematurely stop. Is there no workaround for this - ie. some way I could invoke Linux ffmpeg from WINE? – J23 Jun 27 '20 at 07:57
  • @Metal450, when you run a Linux cli-application from the Wine command line (e.g. `cmd.exe`), it is `cmd.exe` who handles the pipes, and it handles them properly (at least in Wine 2.0.1). Point 5 is about the case when you run a Linux application using Windows API (i.e. CreateProcess function) and should handle the pipes by yourself. – ruvim Jun 29 '20 at 14:23
  • From cmd.exe, are you able to get any output from i.e. `start /unix /usr/bin/git` or `start /unix /usr/bin/ffmpeg`? – J23 Jun 29 '20 at 17:44
  • Try `/bin/ls`. Don't use `start`, it is not suitable to run a Linux command (i.e. cli-application). If you need to start a command in a new window, use `cmd` wrapper, e.g.: `start cmd /k /bin/ls` – ruvim Jun 30 '20 at 01:45
  • Sorry, I don't really understand that answer. I'm trying specifically to invoke ffmpeg from WINE - as an initial proof of concept I was trying to run it from cmd, but was unable to see any output. You said not to use `start`, but isn't `start /unix` the given way to run a Linux command? Wasn't that the original poster's question? – J23 Jun 30 '20 at 07:47
  • (To be even more specific, I'm trying to figure out how to get FFmpeg Batch AV Converter - https://sourceforge.net/projects/ffmpeg-batch/ - to be able to invoke the Linux native version of ffmpeg. The UI works great in WINE, and it *can* invoke the Windows version of ffmpeg, but it's considerably slower. It's open-source, & the dev - who isn't me - has worked to get it running under WINE. However, I use it a lot & am trying to help him figure out how to do this last piece of the puzzle.) – J23 Jun 30 '20 at 07:49
  • @Metal450: Were you ever able to get this working? I'm trying to do something similar and see a lot of comments from you on different questions I'm coming across looking for information about this. – BrenBarn Oct 04 '20 at 07:33
  • Nope, never did. Please let me know if you do. – J23 Oct 05 '20 at 08:03
  • @Metal450, @BrenBarn, I [was wrong](https://stackoverflow.com/questions/6004070/execute-shell-commands-from-program-running-in-wine#comment110774890_45545068) that `cmd.exe` can properly run and wait a Linux program. I have created a [small program](https://github.com/ruv/wine-runio) that can help to run Linux programs from WineHQ. You might want to [test it](https://github.com/ruv/wine-runio/releases). Comment [in GitHub](https://github.com/ruv/wine-runio/issues) please, if any. – ruvim Oct 07 '20 at 11:11
  • Thanks for the reply! Unfortunately, it doesn't seem to be working for me - will post a follow-up on your github. – J23 Oct 07 '20 at 21:21
  • @ruvim: I also couldn't figure out how to use your tool. – BrenBarn May 24 '22 at 08:14
4

Try (where yourprogram is the linux/unix program you want to execute in wine)

ln -s /path/to/yourprogram /path/to/wineprefix/drive_c/windows/system32/yourprogram

That is how I have gotten java working.

  • 1
    This doesn't seem to work for some (?) command-line applications - i.e. ffmpeg, git, etc. It doesn't show an error, nor any output. Just nothing. Are you seeing different? – J23 Jun 27 '20 at 07:49
2

For example:

Z:\bin\ls

But maybe you are looking rather for something like http://gnuwin32.sourceforge.net/ that you will install into your wine "windows"? Or the already mentioned cygwin.

David L.
  • 3,149
  • 2
  • 26
  • 28
2

for me the first solution I found on this site worked - associating an extension with winebrowser, and default gnome file viewer launches from wine when clicking on a file in wine explorer (or in other windows applications).

Previous solution with shell scripts, which worked in wine 1.4, does not work with wine 1.6.

However, the problem I noticed is that names in Windows encoding are not converted to Linux locale, preventing this to work with e.g. Russian directory names

David S
  • 12,967
  • 12
  • 55
  • 93
Eugene
  • 101
  • 1
  • 6
0

The shell script that was listed on WineHQ FAQ can be slightly modified, eg like this:

#!/bin/bash
WFILE=$(echo -E $2)
FILE=$(wine winepath $WFILE)
$1 $FILE

The rest works just as described in the FAQ.

  • I haven't been able to get any of these methods to work under current (1.8/1.9) Wine running under OS X. I can get the wineconsole to open, but I'm trying to find some way to run (for example) the OS X Calculator. This does NOT work: `cmd /c start /unix open /Applications/Calculator.app` (or any other command that works in the OS X Terminal). Does anyone have any up-to-date information, please? – emendelson Mar 22 '16 at 16:26
  • 1
    @emendelson /Applications/Calculator.app is a folder the real app lies inside /Application/Calculator.app/Contents/MacOS .You can explore the contents by opening a console and entering “ls /Application/Calculator.app/Contents/MacOS” there. – Keinstein Jul 28 '16 at 07:49
0

I love the Far Commander, which does run under wine, so I set up these two scripts:

  1. To launch Linux applications from windows

C:\windows\xt.bat

start /unix /usr/bin/xterm -e %*
  1. To open files in Linux from the wine environment (Far):

C:\windows\xdg.bat

cd >C:\windows\command\mypwd
start /unix /etc/init.d/winopen.sh  %*

/etc/init.d/winopen.sh

#!/bin/sh
PWDF=`winepath -u 'C:\windows\command\mypwd'`
fromdos $PWDF
xdg-open $(winepath -u $(cat $PWDF)/$1)

Now I can type on the Far command line:

xt top

xdg SomeDocument.PDF

and get results in the Linux environment.

Community
  • 1
  • 1
MKaama
  • 1,732
  • 2
  • 19
  • 28
0

Edit: user1182474's comment is correct; Wine doesn't isolate the programs it runs. (It tries to hide it, but not very thoroughly.) I totally failed at using Google. Psen's comment below is more correct, and references the FAQ. (Note that, for that to work, you may need to have the program's directory available through a Wine drive mapping. Or, see Anonymous Replier's answer.)

== Old Answer ==

Wine isolates the programs it runs. The applications are, if all works as intended, presented with an environment indistinguishable from Windows. Unfortunately for your purposes, that means that you can't access the features of the host OS (Linux). I mean, you could patch Wine to do that, but I get the impression that it would be more work than it's worth.

There is hope! Cygwin is a Unix-like environment for Windows. You could install Cygwin in Wine, and use Cygwin to run your shell script. (Apparently, installing with 'winetricks cygwin' is easiest) Invoke Cygwin's bash shell (inside some Wine program) like this:

c:\cygwin\bin\bash  myscript

Of course, change c:\cygwin to wherever you install it.

Daniel Ralston
  • 2,230
  • 21
  • 15
0

Use SSH if you need to wait for the command to complete and get it's output. Otherwise (if you need only to start it) any of these methods will work:

The core problem is that CreateProcess returns zero PID and handle, so you can't wait for the child process completion and get it's exit code.

I've also tried standard pipes redirection with no luck. The output of Linux child process is lost, pipes are empty.

So, with CreateProcess and friends you have to use some kind of trigger files, which looks not too beautiful. Like I said, we're going to use SSH instead.

Aleksandr
  • 339
  • 3
  • 6