shell 2013 (2017 update, Windows version)

Jeremy's icon

Hi y'all,

Bill Orcutt's 'shell' object has gotten a bit long in the tooth and it was time for a major cleanup and, er, a complete rewrite, actually. An "early beta" is attached to this post, so give 'er a spin and let me know how it goes.

Changes:
- complete rewrite :-)
- initial implementation of interactive shell functionality:
  - 'penter': if an interactive command is running, send the text + a carriage return
  - 'pwrite': if an interactive command is running, send the text (no CR added)
but it's still pretty rough ("top -s 1 -l 3600 -stats pid\,cpu\,time\,command" works, but can't be controlled interactively, for instance. I could successfully SSH to another computer, though).
- infrastructure for a Windows CMD version added (but no, there's not a Windows version yet and may not be for some time).
- new @stderr to optionally merge stderr with stdout

Known issues:
- not really well-tested yet

shell_170717.zip
application/zip 31.28 KB
Last version of Mac (.mxo) + Windows (.mxe/.mxe64) externals

shell.maxhelp
maxhelp 18.51 KB
Help file (not changed since 2013, needs an update)

kleine's icon

lekker! Thanks, Jeremy!

vichug's icon

Thanks, thsi is a very useful object. One question though : does that update mean that now you can open an aplication which has no graphical interface ? or a command line application ?

Jeremy's icon

You'll need to provide an example. I'm not quite sure what you want to do.

vichug's icon

Well anyway it seems to work, previously i could'nt make it work, but error was probably on my side, related more to bad filepath formatting (need \\ inside " " for each blank space ; \ is not enough) than this update...

vichug's icon

...and what i tried to do is : launching an application which doesn't have a graphical interface, through [shell]. It should be the same than an application with a graphical interface. That's why my question could be confusing...

...Regarding the commandline applications, it is another question ; which answer is "yes, you can" using the new penter/pwrite message.

This is awesome ! thanks ! sorry for the confusing/confused questions :)

Jeremy's icon

An application without a graphical interface is the same as a command line application, as far as I'm concerned. Anyway, yes, it all seems to be working for me. I've made a few improvements and updated a new version of the object to the original post: shell.mxo_1.zip

vichug's icon

it's an application that opens in a separate process than commandline, which you can't interact with in console, but has no gui ; you just see its icon in the dock when it's running. Then maybe it does have a gui, but an empty gui ; and maybe it's an unwise programming practice !...

Jeremy's icon

Ah ok, you mean a faceless background application, I guess. The point of the 'shell' object is to provide access to the OS shell -- so you can launch or kill such an application, you can run an Applescript or similar which targets such an application, but if it doesn't provide a command line interface, there's not much you can do with it otherwise.

vichug's icon

Faceless background application, that's it ;) just launching it at a patcher's loading is useful in my case.

Robin Price's icon

Nice work. In the past I've handled shell stuff successfully from pyext, will have to give this a look.

stkr's icon

thanks jeremy, you are a legend. this is big news.

especially excited by:

"infrastructure for a Windows CMD version added"

...with that added, there will be world peace.

dtr's icon

Can someone help me out with my message formatting? Neither of these 2 options work for making ImageMagick produce an animated GIF. The bottom one works in Terminal.

Max Patch
Copy patch and select New From Clipboard in Max.

I tried removing the space from the paths to no avail.

vichug's icon

hmmmm, two possibilities...
1/either in the first case you need \ before each blank space
2/or you need to format the filepaths using conformpath. I can't really do that here since i don't have imagemagick

Max Patch
Copy patch and select New From Clipboard in Max.

eitherway, sending something in hyphens (" ") should not work, you need the \ before each hyphen.

vichug's icon

(it seems to be something else entirely)

dtr's icon

hey tanx, I ultimately went the pyext way since I need windows support as well

I had tried the \'s though

hhelt's icon
Max Patch
Copy patch and select New From Clipboard in Max.

perhaps this helps:

ubu's icon

Thanks! Great!

If I want AppleScript Editor to run a script, what message do I have to send to the shell object?

Thanks!

Liang's icon

Hahahah ! it toggled the system shell!!

Jeremy's icon

@ubu, you want "osascript": more info

_src's icon

Hi All-
I'm having a heck of a time being able to ssh to another computer.
My message into [shell] is as follows:

ssh (username)@(localIP)

It works like a champ in Terminal, but I can't get it to respond in Max.

I'm an sound/interface guy and I don't have a ton of experience in terminal, but I've searched all over the forums and other sites for answers, and I just can't seem to find out what I'm doing wrong.

Suggestions?

jvkr's icon

Recently I was working with shell and realised that, where commands in Terminal are executed with default arguments, in this case you need to provide them. I understand that's why, as an example, you can type top in Terminal, but in max that doesn't work (and top -s 1 -l 3600 -stats pid\,cpu\,time\,command does). The ssh command I don't (didn't) know, but I see that typing ssh [Enter] in the Terminal gives all possible arguments. Does this make any sense?

leafcutter's icon

I'm investigating making an editor for Composers Desktop Project using shell but I can't seem to change directory with cd. I'm not a pro with terminal but I expect that when i send cd ~/sounds i should then be able to do ls to see whats in the folder - am I misunderstanding?

pdelges's icon

@leafcutter: it's true in a real shell, but cd doesn't seem to work in the shell object (nor does pushd). pwd returns the current working directory, and always returns /ls -l ~/sounds does work.

leafcutter's icon

Yes that what I thought I was seeing with the shell object.

In CDP in terminal you would negotiate to your sounds folder, then run something like:

filter fixed 1-2 soundin.wav soundout.wav boost/cut freq

I tried:

filter fixed 1-2 ~/sounds/soundin.wav ~/sounds/soundout.wav boost/cut freq

But it didn't work, does anyone have a clue as to how I might be able to get it to work?
I would be great to have an editor for the amazing treatments available in CDP.

leafcutter's icon

Ive managed to find a way of doing it. Write the command as a text file, then set its permissions and then run it. Seems to work.

Frans-Jan Wind's icon

Hi All,

In my user home folder .bash_profile file I've added an alias to an applescript like this:
alias spotify="osascript /Users/name/Documents/SpotifyControl.scpt"

In the terminal I now can use the command spotify, but when I try to pass this command to the shell.mxo object I get this as output:
stdout: sh: spotify: command not found

How do I make this shell object aware of the paths and aliases in .bash_profile?

Best,
Frans-Jan Wind

Frans-Jan Wind's icon

I've got it working
Just pass the scriptname as command like this:
osascript /Users/name/Documents/SpotifyControl.scpt next

Tj Shredder's icon

@Jeremy: will there be a 64-bit version? I am more and more forced to go 64-bit (my patches grow too big...;-)

11OLSEN's icon

have you tried it? i'm pretty sure i used it in a 64bit environment. both versions should be combined in one file for mac externals. O.

klaus filip's icon

thanks for the update on shell, jeremy !!
i was looking into shell now again, since i want to workaround the sleeping [suspend] external.
but i am not too familiar with all the unix-commands, can anybody think of a way
"getting the current frontmost application" out of shell?
\thx klaus

Frans-Jan Wind's icon

You could do this by calling a applescript through osascript
In applescript you can make any application frontmost or query "System Events" to get the current front most

Tj Shredder's icon

It is 64-bit, I had a version clash with an old shell object from Jamoma...

kjelgaard's icon

I've been using this heavily lately and am getting used to the quirks. Cant figure out stderr argument though. How does it work?

tomschofieldart's icon

Hi folks,

A simplish(?) question. Is there a way to thread the shell object? I'm using it as an interface to text-to-speech on osx so sending commands like this:

'say "hello world" '

That works fine but I'd like to be able to say things in an overlapping fashion. In the terminal I can open several terminal windows and execute the command in one after another causing the speech to overlap. I don't understand what's going on in the background with this object so it's hard to know where to go. I tried using 'nohup COMMAND &' to return to the prompt which works in a terminal window but not with this object. Any ideas?

thanks in advance for any pointers

Frans-Jan Wind's icon

Hi Tom,

You could put the shell in a poly~ and treat it like any other polyphonic synth.

michaelian ennis's icon

I am using the shell extension to allow me to run python code I have written to remotely control gear. Each time I open max and the patcher 'shell' comes in as jbogus. If I double click the shell.mxo and retype shell in the object it gets updated. I have this external stored in:

/Users/mennis/Documents/Max\ 7/Packages/externs/shell.mxo

My default Folder for device projects is set to:
"main:/Users/mennis/Documents/Max 7/Max for Live Devices"

while my folder for Projects is set to:
"main:/Users/mennis/Documents/Max 7/Projects"

vichug's icon

I would like to launch a command-line application i installed recently, node.js, but when i send the message (node 2>&1) to [shell], i get a :sh: node: command not found
However if i try the same thing from the terminal, it works normally. Is there somewhere i should install that command-line application again ?

@Michealian ennis : in the "package" folder, there is a precise folder structure to follow, otherwise it's bound to be bogus at some point
In this case it should be something like
/Users/mennis/Documents/Max\ 7/Packages/externs/externals/shell.mxo
or
/Users/mennis/Documents/Max\ 7/Packages/shell/externals/shell.mxo

vichug's icon

i just solved my problem... Apparently, Max's shell doesn't have access to user-installed command line tools, so by entering the full path of the command-line tool instead of just the command line ; [shell] can find it and the problem is solved. In my case it was there :
/usr/local/bin/node
it's probably a common place for installed command line tools ?..
There should be a way to simplify this ; but i don't know it

Mr Kabelbruch's icon

Jeremy, thank you a lot for this. For me it brings max to a new level!

Is there anyone who would share a example for a ssh connection. When I send 'ssh user@Ip' the terminal waits for a password. When I send the password in a second message -> there is no reaction anymore from the terminal. If anyone has a solution for this, please share!

Luke Woodbury's icon

I'm also trying to ssh, I'm prompted for a password, but entering it receives no response at all. Anyone managed to do this?

vichug's icon

in the terminal you need input each letter of the password sequentially ; did you try sending each password character one after the other to shell ? or maybe sending the pass with penter ?

Luke Woodbury's icon

I tried entering them sequentially with separate message boxes for each character but that didn't work. Not sure if I'm using penter right, tried a message box with [password penter] and [password -penter] but didn't work either.

Luke Woodbury's icon

Needed enter first:
ssh servername
penter password

Then penter for commands too:
penter cd
penter ls
etc etc

T Bruce's icon

Well, this seems to be the place to ask for a little help using shell to report MaxMSP memory usage in real time from within Max.

I've managed to get "top" spitting out data, but it is not reporting memory usage, only CPU usage.

Also, can't seem to figure out how to parse it so I just get MaxMSP related information.

I'm very new to this. If anyone is willing to help, or point me down a path to edgicate myself, I would appreciate it very much.

ShellForMaxMem.maxpat
Max Patch
juandaco's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Hello guys. First of all, thanks to Jeremy for this wonderful object. I've created a patch using [shell] capable of reporting Max's Memory (@T_BRUCE what you needed) and overall CPU usage (useful for Jitter users). It uses two instances of [shell] to get Max's PID and then get the desired info. Hope this is helpful!

keepsound's icon

Hi, when I try to perform a cp command to copy a file to a protected directory like Library/Frameworks, I have to precede the cp cpmmand with a sudo -v command, but where I have to put the password? I have to append penter? this makes reapparing the password question...confused.
Example: sudo -v penter...no success, or sudo -v pwrite ....no success. What string should I use?

keepsound's icon

Maybe I've found: this seems to be working: echo password' | sudo -S penter

kleurbleur's icon

Did anybody succeed in opening a python file?

python ~/Desktop/test.py
/usr/bin/python ~/Desktop/test.py
usr/bin/python ~/Desktop/test.py

all didn't work, whereas in the Terminal it did.

keepsound's icon

maybe try prepending the word open:
open ~/Desktop/test.py
or
open python ~/Desktop/test.py

keepsound's icon

Set first the application witch you need to open the file (IDLE or Phyton launcher), then run the shell patch.

Schermata-2015-09-05-alle-01.13.27.png
png
Schermata-2015-09-05-alle-01.13.50.png
png
kleurbleur's icon

Okay, formatting is key so I ended up using [textedit] instead of [message] which made it al work, except for user installed programs. Thanks though!

dodgeroo's icon

Hi,

I'm trying to create what I thought would be a simple patch to print a blank document from my printer with Max. No luck so far. This is what I have. Any of you able to tell what I'm doing wrong?

I'm using Max7 on a macbook pro os 10.10

Thanks,

Max Patch
Copy patch and select New From Clipboard in Max.

Carey

kleurbleur's icon

Works fine with me. Although I did remove the 1 before pr.
And just to be sure. Pr prints the file to the standard output of the shell, not the printer. LPR does that but I'm not sure how you need configure that.

Max Patch
Copy patch and select New From Clipboard in Max.

Open up terminal and type: man lpr
to check how that works. I never tried it.

dodgeroo's icon

Nevermind, my printer was paused :-/

Max Patch
Copy patch and select New From Clipboard in Max.

Here is the working patch for anyone else who wishes to print from Max

aceslowman's icon

pkill seems to crash Max, all else with top seems to be working well though!

webe's icon

Great stuff!

I was wondering how one could launch an application, that is valid for different users?open ~/Documents/Max 7/Library/foo/bar
doesn't work for me, whileopen /Volumes/hdd/foo/bar
works!

_HasBeen_'s icon

Hello,
I'm trying to use ffmpeg command with [shell] to convert video files, but with no success (it works perfectly within terminal).
Is there another way to do it within max? Thanx

_HasBeen_'s icon
Max Patch
Copy patch and select New From Clipboard in Max.

Hello,
I’m trying to use ffmpeg command with [shell] to convert video files, but with no success (it works perfectly within terminal).
Is there another way to do it within max? Thanx

_HasBeen_'s icon
Max Patch
Copy patch and select New From Clipboard in Max.

Thanx to vichug for his post from FEBRUARY 4, 2015 | 8:17 PM cause it works :)

Yoann's icon

I posted this question in a separated thread, but maybe it's better here:

I started thinking about using the system tag in 10.10 and above (maybe 10.9 also)
I found this command line which does a great job in the terminal: https://github.com/jdberry/tag
Now I would like to find a way to use it inside max.
Just sending tag command to shell does not work….
Any thoughts ?

_HasBeen_'s icon

Yoann try sending /usr/local/bin/tag to shell.

Yoann's icon

_HasBeen_, it didn't work but it gave me the right direction, the correct path was /opt/local/bin/tag and now it works !!!
Many thanks, now I have an easy and quick way to build a umenu without having to actually organize the files in folder.
I just tag the files, wherever they are and send "tag --find xxxxxxx" and bam, directly into the umenu with "append".
I get the full path in the menu but it's ok.

Thanks again !

michel8's icon

1. how to execute a script.sh?
Execute in the Terminal sh /Users/XYZ/Desktop/script.sh works fine, but not with max shell.

2. I will close a Terminal window:
also in message box I'm struggling with::
echo -n -e "\033]0;My Window Name\007"
osascript -e 'tell application "Terminal" to close (every window whose name contains "My Window Name")' &

it gives:
echo -n -e "033]0;My Window Name007"
so missing the \

and:
The result is "My Window Name)'" & instead of "My Window Name")' &

Thanks!

keepsound's icon

two ways to try:
1. append to your message the obj conformpath win nothing
2. write your script with \ in a sprintf obj and send it with a bang

michel8's icon

@keepsound thanks for help. I tried it out but unfortunately it does't work.

1. if I type open instead of sh to the max shell, it opens the script.sh in an editor like xcode. So the path works well. It seems that the max shell does not work with sh or bash command.

2. the sprintf takes out the " in the command. osascript -e ‘tell application "Terminal" to close (every window whose name contains "My Window Name")’

michel8's icon
Max Patch
Copy patch and select New From Clipboard in Max.

I find a solution to open a script.sh with sh script.sh shell-command in max shell object.
To close the Terminal window It works also if I know the name of the window. See the patch

vichug's icon

michel8 : did you try turning your script into an executable, i think the command is chmod +x thescript.sh

keepsound's icon

There's a lot of formatting problems with the shell scripts, and they are different if you write osascripts. The problems are backslashes and double quotes (") that are to replaced with single quotes ('). Some are to be escaped, some are to be written in sprintf obj (the messages with backslashes)...Packing two list together with $1 $2 doesn't work, you have to use the obj zl join that retains the backslashes....if I find one of my last scripts, I'll put them here. It's a little nightmare, but at the end they works all.

michel8's icon

thanks Vichug and Keepsound.
Yes I did with chmod +x to made it executable.
Ok, zl join I didnt try. A nightmare example script would be great :)

keepsound's icon

Some examples...

Max Patch
Copy patch and select New From Clipboard in Max.

keepsound's icon

To empty the trash folder...

Max Patch
Copy patch and select New From Clipboard in Max.

Tom Holman-Sheard's icon

Hi Jeremy, I just downloaded your patch, but I'm having problems seeing the chess board (see image). Any thoughts about this? I'm using max 7.
Thanks, Tom.

Screen-Shot-2016-06-10-at-05.12.30.png
png
6l20's icon

Hi Y'all.
Simple problem here, I am using the wonderfull shell object to launch and get feedback from a python script. The script takes quite a while (fetches a lot of info from the internet and does some parsing), about 40secs. I use a lot of "print" inside the python script to get feedback on what is actually going on. If I launch my script with terminal, I get all my infos along the way. If I launch it within max, then I have nothing from the stdout until the script finishes, then I get all my info at once.
Is there a way we can get infos "as they are printed" ? Hope my question is clear...
Thanx

zangpa's icon

Great object!!! How do i terminate a process (like ^C) when i use shell object. trying to stop some say-commands. Thanks!

zangpa's icon

@tomschofieldart
Hi, did you find a way to trigger multiple text to speech at the same time. Did the poly-idea work? I can not get it to work at the moment....

Dalmazzo's icon

Hi

One question, I'm using shell to execute a python script. It works well, but the script make a zip file on the root. My problem is that shell is pointing to the root "/", how can I move to another folder. I just tryed "cd Users" but it keeps always on "/"

Arvid Tomayko's icon

Hi - is the source to this still available? The link to download with source at https://cycling74.com/tools/bernstein-shell/ is no longer clickable. Thanks!

Jeremy's icon

I just put a copy at http://expr-i0.net/shell.zip

Maybe it's time to make a Windows version...

Arvid Tomayko's icon

awesome - thanks!

Jeremy's icon

I just did some experiments on Windows and... I have the object building and passing something to the Windows cmd.exe. Lots of stuff to work out, probably, but I'll keep poking at it.

First light...

11OLSEN's icon

@Jeremy A Windows version is a good idea. Please take into account that you can not simply use the Max utf8 strings to transfer to cmd. It may work most of the times, until there is a wide char in Windows file names/pathes. I'm there if you need help testing/debugging the thing.

Jeremy's icon

Thanks, I'll be using the WCHAR versions of CreateProcess and co., so no worries about that. Once I have something which works a little more reliably, I'll drop some binaries for testing.

One thing I'd personally like is the ability to use the Bash shell (MSYS, MSYS2) if available on Windows -- I almost never use CMD.exe if I can help it. Not quite sure how I want to expose that, but it's on my TODO list.

Jeremy's icon

http://expr-i0.net/shell_win_170716.zip is available for testing (32- and 64-bit binaries). In general, it works just like the OSX version (although I haven't tested it very much and haven't attempted to do any interactive stuff).

It should be Unicode-correct for reading from CMD.exe, although not for writing (apart from the initial command, but that's going to be restricted by Max's use of UTF-8). I believe that you cannot write Unicode to the CMD.exe console, either. I can look closer at it if someone can provide a case where this becomes a problem.

Two new features, which will show up on OSX, too, assuming they prove useful:

@shell sets the shell binary (so you can point it to c:/program files/Git/bin/sh.exe if you want a MinGW shell). (default) or no symbol means use CMD.exe. Note that Unicode is currently only supported for CMD.exe (since I can launch the process explicitly as Unicode).

@wd sets the current working directory for the shell command. The default is the user's $HOMEPATH and failing that, the system32 dir (or wherever your shell is running from).

Enjoy, please give it a try and let me know how it works for you.

11OLSEN's icon

No problems with chars, but it seems not to accept strings with spaces. try this: md "c:\\one two".
Would have been cool if you put a conformpath into the external so we can input the path style of Max. But that's not so important.
    

11OLSEN's icon

wait, forget that thing with conformpath, that does not apply here.

Jeremy's icon

I don't want to start messing with additional args beyond the actual command (which I can conform) -- it's too error-prone. So your example still won't work if I do that.

md \"one two\" works correctly, and is the typical way of escaping quotes in Max, C and in consoles.

11OLSEN's icon

Yes that makes no sense to conform the args. And I forgot to escape the quotes of course. So everything good for now. Thank you

Jeremy's icon

http://expr-i0.net/shell_win_170716b.zip is now up. It conforms the command if possible and attempts to properly quote. So 'md "one two"' will now work (without the escapes). Or '"c:/Program Files/Git/bin/git.exe" --version'. Also contains a fix in case of a read buffer overflow when in CMD.exe (Unicode). And processes attr args. Hopefully no new bugs.

11OLSEN's icon

As it is not yet an official default object, how is that licenced. Are we free to use [shell] in any case?
Commercial, private, whatever?

Jeremy's icon

Our forum doesn't like my phone... Sorry for the brevity. I'll add a license to final release, but there is nothing particularly proprietary or groundbreaking about shell. It remains open source and free, without restriction.

11OLSEN's icon

@Jeremy Thanks again for taking the time.

Jeremy's icon

I've been promising a Windows version for over 10 years, I think. So thanks for your patience and I look forward to more feedback.

Jeremy's icon

http:/expr-i0.net/shell_170717.zip now up. Contains OSX & Windows externs which are more or less what I hope to be the release version. OSX now supports alternative shells (tested a bit with zsh), UTF-8 output and custom working directory. The new default WD on OSX is ~. The quoting and cmd conformance fixes for Windows were also applied to the OSX version.

Source Audio's icon

Many, many thanks. Finally end of dose hack and other java solutions.

stkr's icon

the legend that is jeremy strikes again.

indeed this windows version will bring world peace.

many many thanks <- & now to start hinting this should be in the main distro :) ...

Jeremy's icon

This work had much more to do with a bad cold and a lot of low-concentration downtime than anything else. But thanks for the kind words @stkr (Peter, should I pronounce that sticker, stacker or stinker?).

Although I would love to see shell in the main distro, it raises some security concerns which make it potentially unsuitable. In particular, it's possible to run something like "rm -rf /" (or "rd /s /q c:\" for our new Windows friends) and erase quite a bit of your hard drive, even without using sudo.

I know this, because I tried it once, in public, in a cavalier and humiliating attempt to demonstrate how benign the object is. This was probably 15 years ago, and OSX may be more resilient in the meantime. But back then, I had to restore from a backup and lost some work.

I can imagine one's displeasure when opening someone's awesome new M4L device which contains [loadbang]-(rm -rf ~/)-[shell]. So _not_ including shell in the main distro would prevent a worldwide Maxtastrophe, at least for the many users who don't install edgy third party externals.

Maybe we (C74) don't care, though. But since our patcher format isn't really legible, it's not the same as distributing source code, where you can scan through and see that something funny might be going on. I would personally err on the side of caution.

11OLSEN's icon

I'm afraid that is already possible on Windows by saving batch or vbs script files and executing them with openbrowser message.

stkr's icon

hey jeremy. thanks! it is definitely "stinker", or at least will be from now on :-) as in "that wasn't just a bad cold, it was a complete stinker of a cold", or, "that wasn't just a benign demonstration, it was a complete stinker of a demonstration" (i'd love to have been at that one).

i guess i was using the "should be included in" moniker as a way of expressing how awesome it is, as us end users are inclined to do, rather than a really serious call. but, just out of interest (pleasant & discursive interest) would it be possible to have the object by default in some sort of 'safe mode', where dangerous access could be curtailed, and switching to 'pro mode' would be oblique, for 'experts'?

yours sincerely,
stinker.

Jeremy's icon

@11olsen, the difference is that shell is self-contained. External files might set off alarm bells for anyone who cares to check. But you're right, it's impossible to fully eliminate the chance of malicious software made with Max.

Jeremy's icon

@stkr, I can't think of any way to determine what access is dangerous. We could disable the object entirely unless an application-wide Expert Mode preference has been enabled, which would be something to consider. Homework: what else belongs in Expert Mode?