I'm a complete novice at this (terminal in Mac leopard) and hoping to get an lifeline from the web as I've certainly hit a wall.
I want to run a script as a root in terminal. The script is saved as a text file with a .rtf extension. I've inserted into terminal:
sudo filename.rtf
then I get asked a password which I've typed in (admin password) and pressed enter; then it shows a prompt: sudo: Mac: command not found
I've tried it with the extension hidden but got the same result. Any pointers on what I'm doing wrong?
Thanks in advance
You need to first get the script out of the .rtf file and into a plain text file (open it up in TextEdit and select "Make Plain Text" from the format menu, then save it again as myscript.sh).
Now you can type
sudo sh myscript.sh
The "magic" sh letters there are because as another responder says, sudo will temporarily elevate you to superuser and run a program. In *nix environments, that would be anything with the executable bit set, meaning that someone's explicitly told the operating system that it's safe to run a file. In your case, your myscript.sh has not been "blessed" in this way, so to run it you need to feed it into a program that knows how to understand it. That program is sh, and it does have the executable bit set. Thinking of it as sudo (sh myscript.sh) might make it a bit clearer.
If you plan on running this script a lot, you might want to actually make it executable on its own. This amounts to putting special instructions inside the file that tell the operating system how the file should be run. If you stick #!/bin/sh (this is called a shebang line and tells the OS what to do with your file) on the first line of your script, and then type chmod u+x myscript.sh (this tells the OS that you, and only you, are allowed to execute your file), you'll be able to run the file directly with sudo myscript.sh.
sudo is used to execute commands as the root user of the machine.
when you type
sudo [somthing]
the shell grants temporary root privilges and then executes the given "somthing"
assume your script is in bash, you should have done
sudo sh filename.rtf
Also, it's better to save script as plain txt, with an sh extension, so you would execute
sudo sh myscript.sh
first set the script as executable:
chmod +x filename.rtf
Then you can run it like so:
sudo ./filename.rtf
Related
I'm both new here and with MacOS and coding.
I know in windows I can create bash file to have an executable command in cmd. I've researched and discovered I can use similar file with MacOS (shell files) but I'm struggling to understand how to make one. I've tried different route:
As first thing I've tried creating a file in txt editor with this code:
#!/bin/bash
pip3 install pgzero
echo Installing Pygame Zero
Using later 'chmod 700 Filename' in terminal. It did not worked
I then tried with Apple Scrip, with a code like:
tell application "Terminal"
activate
do script "pip3 install pgzero"
do script "echo Installing Pygame Zero"
end tell
and it kinda worked, but it wasn't an executable
Then I tried with another approach found on google:
echo '#!/bin/bash
pip3 install pgzero
echo Installing PyGame Zero'> ~/Desktop/PygameInstaller.command
chmod 740> ~/Desktop/PygameInstaller.command
and it still didn't worked D:
Can someone land a bit of help? I'm starting feeling lost q,q
Thank you in advance!
In terms of what you want in your shell script, your first attempt is probably close to what you want but the echo should precede the pip3 command. I guess if you change the verb from Installing to Installed, then you could leave it where it is.
$ cat <<EOF > ~/Desktop/PygameInstaller.command
#!/bin/bash
echo Installing Pygame Zero
pip3 install pgzero
EOF
$ chmod 700 ~/Desktop/PygameInstaller.command
The permissions you assign to the script and the script's location depend on who you want to grant execution. If it's only you, then your desktop and 700 should be fine.
Now, if you want to execute the script from a command line like what you would see if you opened an instance of Terminal.app, then you have options.
If you want to fully specify the command, then you would type this (showing prompt which you would not type):
$ ~/Desktop/PygameInstaller.command
If you want to specify only the name of the script, then you would type this after adding ~/Desktop to your PATH:
$ PATH="$HOME/Desktop:$PATH"
$ PygameInstaller.command
If you prefer to type only PygameInstaller, then don't put the code in a file named PygameInstaller.command. Instead, you put the code in a file called simply PygameInstaller.
If you need the script to be executable by everyone, then put it in /usr/local/bin because most people will either have that in their PATH or have no political problem doing so. But you'll have to use the sudo command to elevate your privileges to accomplish that task.
If, however, you want to have that script be treated like any other app that you can launch with a double-click, then you have significantly more work to do.
Original problem: on my MacBook Pro, the video camera keeps freezing. Found the solution is to type
sudo killall VDCAssistant
in a terminal, and provide my password (I have admin privileges).
Now I would like to make this a single command (that doesn't need a password). I found that it is possible to use visudo to edit a file that tells sudo what commands might be run without requiring a password. Obviously it would be too dangerous to make killall itself "password free", so I was hoping I could wrap the specific command inside another script; make that script "password free"; and get on with my life. So here is what I did:
Create a file called video, which contains
!#/bin/bash
sudo killall VDCAssistant
Put it in /usr/local/bin, give permissions chmod 700 video, and rehash. When I type video, I get prompted for my password. So far so good.
Next, I ran visudo and added the lines
User_Alias USERS = myusername
CMND_Alias CMDS = /usr/local/bin/video
USERS ALL = (ALL) NOPASSWD: CMDS
But that doesn't have the desired effect. I am still prompted for the password. If I make root the owner of the script, it doesn't change things. If I leave out the sudo part of the command, it tells me "No matching processes belonging to you were found".
Does anyone have a trick that I missed - how do I achieve my goal (using a single-word command to perform the killall for a process I do not own, without having to type my password)?
I have read the answers to how to run script as another user without password but could not find anything that applied here; I also read the answers to sudo with password in one command line - that is where the inspiration to use visudo came from - but again it didn't give me the answer I was looking for. Obviously I can't save my password in plain text, and I don't want to remove the "normal" protections from killall.
Is there a way to do this?
If you have an actual binary executable, you can set the setuid bit on it using chmod 4755, and then the binary will always execute as whichever user owns it (most useful if it is root, obviously). However, this doesn't work on shell scripts, for security reasons. I'm not 100% sure that this is the case, but it is possible that visudo may also be ignoring shell scripts for the same reasons.
If you've got Xcode installed, though, you can build an actual binary program to run the killall command, and then you can set the setuid bit on it. This Swift program should do the trick:
import Foundation
guard setuid(0) == 0 else {
print("Couldn't set UID 0: error \(errno)")
exit(-1)
}
let killall = Process()
killall.launchPath = "/usr/bin/killall"
killall.arguments = ["VDCAssistant"]
killall.launch()
killall.waitUntilExit()
Save the above in a text file called video.swift. Run the following command:
swiftc video.swift -framework Foundation
This will create a file called video in that directory. Move the file to /usr/local/bin, change the owner to root and setuid that sucker:
mv video /usr/local/bin
sudo chown root:wheel /usr/local/bin/video
sudo chmod 4755 /usr/local/bin/video
Now it should work.
If you want to get fancier, it would probably also be possible to rig up a plist in /Library/LaunchDaemons and get launchd to automatically kill the process every so often.
I'm a total bash noob but try checking this answer, the problem here might be with your sudoers file. I tried replicating your problem and encountered the same behaviour, with this answer I was able to make it work. I can't say anything about safety of this solution. To sum up:
I've created a file called video while logged in as root with following contents:
#!/bin/bash
sudo killall VDCAssistant
set it's permissions chmod 700 video and rehashed
using visudo I've added a following line mysuername ALL=NOPASSWD:ALL below the line %sudo ALL=(ALL:ALL) ALL since myusername is a member of group sudo
sudo video runs the script and kills the process
by adding alias VIDEO 'sudo video' to your .cshrc file, you can make this a true "one word command"
The answer by Charles Srstka solved my immediate problem; subsequent clarifications by #mspaint showed that the script-based answer could in fact also be made to work. I then discovered a nice additional touch that I wanted to share for anyone that runs into this problem. This is "how do you make the whole process seamless".
1) "Hide" the killall command in a script:
Create a text file with the following lines:
#!/bin/bash
sudo killall VDCAssistant
and save it to /usr/local/bin/restartVideo.sh
Change the permissions: chmod 700 restartVideo.sh so only you can run it.
2) make the restartVideo.sh script password-free for use with sudo
Next we need to edit the sudoers file so there is no need to prompt for the password when running the above script. The editing is done by sudo visudo - this edits a copy of the file in vim, and checks it for errors before overwriting the original. Add the following lines to the file:
# my user can run the restartVideo.sh command with sudo without password:
User_Alias ME = myUserName
Cmnd_Alias VIDEO = /usr/local/bin/restartVideo.sh
ME ALL = (ALL) NOPASSWD: VIDEO
This last line actually means "user 'ME' (defined with the User_Alias command), from 'ALL' terminals, and executing as any member of '(ALL)', can without password (NOPASSWD:) execute all commands defined by VIDEO. Save the file - make sure there are no errors / warnings! N.B.: in my original question it appears I had used CMND_Alias instead of Cmnd_Alias; that must have generated a warning that I overlooked ... and it may be the reason my original approach wasn't working (???).
3) Create a Service to invoke the script
For this I turned to the Mac Automator application - in particular, I created a new Service.
Search for the actions that have "run" in their title, and pick "Run shell script":
Using the default shell, run the command sudo /usr/local/bin/restartVideo.sh, taking no inputs. Make the command available to any application.
Finally - save the script as "Restart video".
And by miracle, you get the following menu item (showing it here for Skype):
Now you can just select that menu item, and your camera comes back to life.
I have a simple bash script that throw errors on a Windows machine in the Cygwin xterm terminal when I call it like so: ./myscript.bat. It runs fine when I call it like this: /cygdrive/c/cygwin/bin/bash.exe myscript.bat. I am thinking that my shell is not using bash by default. How can I set it to bash so that the next time I open the shell, I can execute my script using ./myscript.bat?
When you execute a file, Windows (or some component within Windows) decides how to execute it based on the extension part of the file name.
Cygwin inherits this functionality, letting you run Windows commands from within Cygwin. Cygwin also implements most of the usual UNIX functionality (running commands based on their content), but the combination of UNIX and Windows semantics can't always be perfectly clean.
The .bat suffix refers to a Windows batch file, so when you try to execute myscript.bat, the system treats it that way rather than as a bash script.
Change the file name from myscript.bat to myscript.bash or myscript.sh -- or just drop the extension altogether (since someone running your script shouldn't need to care how it's written).
There are several other filename extensions you should avoid (like .cmd), depending on how Windows is configured. A few quick experiments show that a .sh extension is safe, but really you don't need to use an extension at all for a shell script.
And, as R Sahu's answer says, you also need to make sure the script has execute permission if you haven't already done so:
mv myscript.bat myscript
chmod +x myscript
You'll probably need to change permissions of the file to make it an executable.
Try
chmod +x myscript.bat
./myscript.bat
I have tried to search for a simple answer for running a simple script (myscript.sh) from the Ubuntu (13) desktop that would open the terminal, navigate to a folder (/var/www/myproject) and then run the "compass watch" command (and then stay open). First I thought this would be very simple to accomplish, but after several fails and searches, this particular task/script seems overwhelmingly hard to get to work.
To do this manually is not a big task:
Open terminal
navigate "cd /var/www/myproject"
run "compass watch"
I thought this would be a walk in the park (although I am quite new to terminal and scripting), but through the searches I got some weird desktop launcher answers and complicated bash scripting functions solutions for sub-shell work-a-rounds. My question is, can this be done with one single (simple) file that is launched from the desktop?
Either you make a shell script (.sh file, don't forget to make it executable) or you make a desktop file (.desktop). Either of those can be double-clicked, although the former might bring up a dialog asking whether you want to execute it (can be configured, but only per user, IIRC).
myscript.desktop:
[Desktop Entry]
Exec=bash -c 'cd /var/www/myproject && compass watch'
Name=myscript
Terminal=true
Type=Application
(Note the Terminal=true part.)
myscript.sh:
#!/bin/sh
gnome-terminal -e 'cd /var/www/myproject && compass watch'
(Assuming you want to use GNOME Terminal.)
Of course, there are numerous other options.
I didn't get well where is your problem ...
If you want to run a script like that (double clic) you should first make it executable:
chmod u+x myscript.sh
Then you just have to place a link to this script on your desktop (or the script itself if you want ...)
When double-clicking it, you will have the possibility to run it in a terminal.
Then put whatever you want in your script ( the navigate "cd /var/www/myproject" , run "compass watch" part) and end the script (myScript.sh) file with $SHELL to keep the terminal open after the script execution (:
I have a bash script like:
#!/bin/bash
echo Hello world!
How do I execute this in Terminal?
Yet another way to execute it (this time without setting execute permissions):
bash /path/to/scriptname
$prompt: /path/to/script and hit enter. Note you need to make sure the script has execute permissions.
cd to the directory that contains the script, or put it in a bin folder that is in your $PATH
then type
./scriptname.sh
if in the same directory or
scriptname.sh
if it's in the bin folder.
You could do:
sh scriptname.sh
This is an old thread, but I happened across it and I'm surprised nobody has put up a complete answer yet. So here goes...
The Executing a Command Line Script Tutorial!
Q: How do I execute this in Terminal?
The answer is below, but first ... if you are asking this question, here are a few other tidbits to help you on your way:
Confusions and Conflicts:
The Path
Understanding The Path (added by tripleee for completeness) is important. The "path" sounds like a Zen-like hacker koan or something, but it is simply a list of directories (folders) that are searched automatically when an unknown command is typed in at the command prompt. Some commands, like ls may be built-in's, but most commands are actually separate small programs. (This is where the "Zen of Unix" comes in ... "(i) Make each program do one thing well.")
Extensions
Unlike the old DOS command prompts that a lot of people remember, you do not need an 'extension' (like .sh or .py or anything else), but it helps to keep track of things. It is really only there for humans to use as a reference and most command lines and programs will not care in the least. It won't hurt. If the script name contains an extension, however, you must use it. It is part of the filename.
Changing directories
You do not need to be in any certain directory at all for any reason. But if the directory is not on the path (type echo $PATH to see), then you must include it. If you want to run a script from the current directory, use ./ before it. This ./ thing means 'here in the current directory.'
Typing the program name
You do not need to type out the name of the program that runs the file (BASH or Python or whatever) unless you want to. It won't hurt, but there are a few times when you may get slightly different results.
SUDO
You do not need sudo to do any of this. This command is reserved for running commands as another user or a 'root' (administrator) user. Running scripts with sudo allows much greater danger of screwing things up. So if you don't know the exact reason for using sudo, don't use it. Great post here.
Script location ...
A good place to put your scripts is in your ~/bin folder.
You can get there by typing
# A good place to put your scripts is in your ~/bin folder.
> cd ~/bin # or cd $HOME/bin
> ls -l
You will see a listing with owners and permissions. You will notice that you 'own' all of the files in this directory. You have full control over this directory and nobody else can easily modify it.
If it does not exist, you can create one:
> mkdir -p ~/bin && cd ~/bin
> pwd
/Users/Userxxxx/bin
A: To "execute this script" from the terminal on a Unix/Linux type system, you have to do three things:
1. Tell the system the location of the script. (pick one)
# type the name of the script with the full path
> /path/to/script.sh
# execute the script from the directory it is in
> ./script.sh
# place the script in a directory that is on the PATH
> script.sh
# ... to see the list of directories in the path, use:
> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ... or for a list that is easier to read:
> echo -e ${PATH//:/\\n}
# or
> printf "%b" "${PATH//:/\\n}"
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
2. Tell the system that the script has permission to execute. (pick one)
# set the 'execute' permissions on the script
> chmod +x /path/to/script.sh
# using specific permissions instead
# FYI, this makes these scripts inaccessible by ANYONE but an administrator
> chmod 700 /path/to/script.sh
# set all files in your script directory to execute permissions
> chmod +x ~/bin/*
There is a great discussion of permissions with a cool chart here.
3. Tell the system the type of script. (pick one)
Type the name of the program before the script. (Note: when using this method, the execute(chmod thing above) is not required
> bash /path/to/script.sh
...
> php /path/to/script.php
...
> python3 /path/to/script.py
...
Use a shebang, which I see you have (#!/bin/bash) in your example. If you have that as the first line of your script, the system will use that program to execute the script. No need for typing programs or using extensions.
Use a "portable" shebang. You can also have the system choose the version of the program that is first in the PATH by using #!/usr/bin/env followed by the program name (e.g. #!/usr/bin/env bash or #!/usr/bin/env python3). There are pros and cons as thoroughly discussed here.
Note: This "portable" shebang may not be as portable as it seems. As with anything over 50 years old and steeped in numerous options that never work out quite the way you expect them ... there is a heated debate. The most recent one I saw that is actually quite different from most ideas is the "portable" perl-bang:
#!/bin/sh
exec perl -x "$0" "$#"
#!perl
Firstly you have to make it executable using: chmod +x name_of_your_file_script.
After you made it executable, you can run it using ./same_name_of_your_file_script
Change your directory to where script is located by using cd command
Then type
bash program-name.sh
And yet one more way
. /path/to/script
What is the meaning of the dot?
If you are in a directory or folder where the script file is available then simply change the file permission in executable mode by doing
chmod +x your_filename.sh
After that you will run the script by using the following command.
$ sudo ./your_filename.sh
Above the "." represent the current directory.
Note!
If you are not in the directory where the bash script file is present then you change the directory where the file is located by using
cd Directory_name/write the complete path
command. Otherwise your script can not run.