I am trying to install rEFInd to a FAT formatted partition on a 2018 mac mini. The version of rEFInd is 0.12.0. The output from the command diskutil list disk0 is given below.
The command I entered was sudo ./refind-install --usedefault /dev/disk0s4. The error messsage was sed: -i may not be used with stdin. I believe the line in the script causing this messsage is given below.
sed -i 's/#showtools shell/showtools install, shell/g' "$InstallDir/$TargetDir/refind.conf"
I made the following correction to get the script to work.
sed -i '' 's/#showtools shell/showtools install, shell/g' "$InstallDir/$TargetDir/refind.conf"
Last edit: David Anderson 2020-10-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Another change I would make is to allow the EFI partition to already be mounted or not. The code code check if it was mounted, and mount it if it wasn't. InstallDir would point to the mounted location. Here's a function I made to mount a partition and/or get it's mount point location (works in macOS - needs minor changes for Linux):
# mount a partition
mountpartition(){localmounttype=$1localslice=$2localvolume=$3localmountpoint=$(mount | sed -n -E "/\/dev\/$slice on (.*) \(.*/s//\1/p")if[ -z $mountpoint];theni=0localstartmountpoint="/Volumes/$volume"mountpoint="$startmountpoint"while[ -d "$mountpoint"];do((i++))mountpoint="$startmountpoint$i"donefiif[ ! -d "$mountpoint"];then
sudo mkdir "$mountpoint"2> /dev/null
sudo mount$mounttype"/dev/$slice""$mountpoint"fiecho -n "$mountpoint"}
where $slice is disk0s4 in your case. $volume would be whatever you like (refind_install in the case of the refind script). Maybe replace the part of the code that looks for an unused name in /Volumes with a temp folder path guaranteed to be unused (use mktemp -d).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The script is not wrong. sed -i 'XYZ' is a standard form for sed as implemented on Linux.
Apple implemented the "non-standard" sed -i '' 'XYZ' form on Macs ... which it seems you are using.
Last edit: dakanji 2020-10-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I encountered a problem where if I ran the command sudo ./refind-install --usedefault /dev/disk0s4 again after removing install from showtools. Here a message is displayed stating refind.conf will not be changed, but is in fact changed. In othe words, install is again added to refind.conf. The part of the script where the problem exists is given below.
if[[-f"$InstallDir/$TargetDir/refind.conf"]];thenecho"Existing refind.conf file found; copying sample file as refind.conf-sample"echo"to avoid overwriting your customizations."echo""cp-f"$ConfFile""$InstallDir/$TargetDir"if[[$?!=0]];thenProblems=1fielseecho"Copying sample configuration file as refind.conf; edit this file to configure"echo"rEFInd."echo""cp-f"$ConfFile""$InstallDir/$TargetDir/refind.conf"if[[$?!=0]];thenProblems=1fifi# If installing to the fallback/EFI default filename, make a duplicate copy# of refind.conf and edit the main copy to include the "install" and "bootorder"# options, so that the system can be used to install rEFInd if it's on a USB# flash drive or CD-R....if[["$TargetDir"=='/EFI/BOOT']];thencp-f"$ConfFile""$InstallDir/$TargetDir/refind.conf-sample"sed-i's/#showtools shell/showtools install, shell/g'"$InstallDir/$TargetDir/refind.conf"fi
I suggest the following replacement. This replacement also solves the problem with the -i option by elimiating the option from the sed command.
# If installing to the fallback/EFI default filename, make a duplicate copy# of refind.conf and edit the main copy to include the "install" and "bootorder"# options, so that the system can be used to install rEFInd if it's on a USB# flash drive or CD-R....localDestConfFile="$InstallDir/$TargetDir/refind.conf"if[[-f"$InstallDir/$TargetDir/refind.conf"]];thenif[["$TargetDir"=='/EFI/BOOT']];thenecho"Existing refind.conf file found; leaving this file unchanged."echo"Copying sample file as refind.conf-sample. This file is"echo"different from the refind.conf file that would have been"echo"created, if refind.conf did not already exist."echo""DestConfFile="$InstallDir/$TargetDir/refind.conf-sample"elseecho"Existing refind.conf file found; copying sample file as refind.conf-sample"echo"to avoid overwriting your customizations."echo""DestConfFile="$InstallDir/$TargetDir"fielseif[["$TargetDir"=='/EFI/BOOT']];thenecho"Copying sample configuration file as refind.conf; edit this file to configure"echo"rEFInd. Copying sample file as refind.conf-sample. This file is different"echo"from the refind.conf file."echo""rm-f"$DestConfFile"&&sed's/#showtools shell/showtools install, shell/g'"$ConfFile">"$DestConfFile"if[[$?!=0]];thenProblems=1fiDestConfFile="$InstallDir/$TargetDir/refind.conf-sample"elseecho"Copying sample configuration file as refind.conf; edit this file to configure"echo"rEFInd."echo""fificp-f"$ConfFile""$DestConfFile"if[[$?!=0]];thenProblems=1fi
Last edit: David Anderson 2020-10-03
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I encounter a problem where if I ran the command sudo ./refind-install --usedefault /dev/disk0s4 again after removing install from showtools. Here a message is displayed stating refind.conf will not be changed, but is in fact changed. In othe words, install is again added to refind.conf. The part of the script where the problem exist is given below.
if[[-f"$InstallDir/$TargetDir/refind.conf"]];thenecho"Existing refind.conf file found; copying sample file as refind.conf-sample"echo"to avoid overwriting your customizations."echo""cp-f"$ConfFile""$InstallDir/$TargetDir"if[[$?!=0]];thenProblems=1fielseecho"Copying sample configuration file as refind.conf; edit this file to configure"echo"rEFInd."echo""cp-f"$ConfFile""$InstallDir/$TargetDir/refind.conf"if[[$?!=0]];thenProblems=1fifi# If installing to the fallback/EFI default filename, make a duplicate copy# of refind.conf and edit the main copy to include the "install" and "bootorder"# options, so that the system can be used to install rEFInd if it's on a USB# flash drive or CD-R....if[["$TargetDir"=='/EFI/BOOT']];thencp-f"$ConfFile""$InstallDir/$TargetDir/refind.conf-sample"sed-i's/#showtools shell/showtools install, shell/g'"$InstallDir/$TargetDir/refind.conf"fi
I suggest the following replacement. This replacement also solves the problem with the -i argument.
# If installing to the fallback/EFI default filename, make a duplicate copy# of refind.conf and edit the main copy to include the "install" and "bootorder"# options, so that the system can be used to install rEFInd if it's on a USB# flash drive or CD-R....localDestConfFile="$InstallDir/$TargetDir/refind.conf"if[[-f"$InstallDir/$TargetDir/refind.conf"]];thenif[["$TargetDir"=='/EFI/BOOT']];thenecho"Existing refind.conf file found; leaving this file unchanged."echo"Copying sample file as refind.conf-sample. This file is"echo"different from the refind.conf file that would have been"echo"created, if refind.conf did not already exist."echo""DestConfFile="$InstallDir/$TargetDir/refind.conf-sample"elseecho"Existing refind.conf file found; copying sample file as refind.conf-sample"echo"to avoid overwriting your customizations."echo""DestConfFile="$InstallDir/$TargetDir"fielseif[["$TargetDir"=='/EFI/BOOT']];thenecho"Copying sample configuration file as refind.conf; edit this file to configure"echo"rEFInd. Copying sample file as refind.conf-sample. This file is different"echo"from the refind.conf file."echo""rm-f"$DestConfFile"&&sed's/#showtools shell/showtools install, shell/g'"$ConfFile">"$DestConfFile"if[[$?!=0]];thenProblems=1fiDestConfFile="$InstallDir/$TargetDir/refind.conf-sample"elseecho"Copying sample configuration file as refind.conf; edit this file to configure"echo"rEFInd."echo""fificp-f"$ConfFile""$DestConfFile"if[[$?!=0]];thenProblems=1fi
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Joevt: I looked an your script to mount a partition. I would not make the mount point in the /Volumes folder. Instead, I would keep using the /tmp/refind_install mount point, when a volumn needs to be mounted. I am not sure why you felt the need to loop until a directory does not exist. Perhaps this is because your script uses the /Volumes folder?
When using the --usedefault option, I found refind-install allows installations to mounted volumes after making the following changes.
First, I made the change suggested in my previous post.
Next, I replaced the following function in refind_install.
# Mount the partition the user specified with the --usedefault or --ownhfs option
MountDefaultTarget() {
local FileSystemType="" Command=""
local EscapedTargetPart="${TargetPart//\//\\/}"
if [[ $OSTYPE == darwin* ]] ; then
Command="/^$EscapedTargetPart on (.+) \(.+/s//\1/p"
if [[ $OwnHfs == '1' ]] ; then
FileSystemType="hfs"
else
FileSystemType="msdos"
fi
elif [[ $OSTYPE == linux* ]] ; then
Command="/^$EscapedTargetPart on (.+) type .+ \(.+/s//\1/p"
FileSystemType="vfat"
fi
InstallDir="$(mount|sed -n -E "$Command")"
test -n "$InstallDir"
UnmountEsp="$?"
if [[ $UnmountEsp == '1' ]]; then
InstallDir="/tmp/refind_install"
mkdir -p "$InstallDir"
mount -t "$FileSystemType" "$TargetPart" "$InstallDir"
if [[ $? != 0 ]] ; then
echo "Couldn't mount $TargetPart ! Aborting!"
rmdir "$InstallDir"
exit 1
fi
fi
} # MountDefaultTarget()
Finally, I removed the exit command from the CreateBootCsvFile funtion. Can you explain why this exit command is needed? This would appear to be a bug.
Last edit: David Anderson 2020-10-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I could have used the sudo diskutil mount command instead. My command is more portable (requires some modification for Linux). diskutil mount will do what my command does - check if the device is already mounted, and if not, then mount to a new mount point. My command returns "EFI", "EFI1", "EFI2", etc. diskutil will do "EFI", "EFI 1", "EFI 2", etc. I use /Volumes so the mount point appears in the Finder desktop automatically.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Joevt: I looked an your script to mount a partition. I would not make the mount point in the /Volumes folder. Instead, I would keep using the /tmp/refind_install mount point, when a volumn needs to be mounted. I am not sure why you felt the need to loop until a directory does not exist. Perhaps this is because your script uses the /Volumes folder?
When using the --usedefault option, I found refind-install allows installations to mounted volumes after making the following changes.
First, I replaced the following function in refind_install.
# Mount the partition the user specified with the --usedefault or --ownhfs option
MountDefaultTarget() {
local FileSystemType="" Command=""
local EscapedTargetPart="${TargetPart//\//\\/}"
if [[ $OSTYPE == darwin* ]] ; then
Command="/^$EscapedTargetPart on (.+) \(.+/s//\1/p"
if [[ $OwnHfs == '1' ]] ; then
FileSystemType="hfs"
else
FileSystemType="msdos"
fi
elif [[ $OSTYPE == linux* ]] ; then
Command="/^$EscapedTargetPart on (.+) type .+ \(.+/s//\1/p"
FileSystemType="vfat"
fi
InstallDir="$(mount|sed -n -E "$Command")"
test -n "$InstallDir"
UnmountEsp="$?"
if [[ $UnmountEsp == '1' ]]; then
InstallDir="/tmp/refind_install"
mkdir -p "$InstallDir"
mount -t "$FileSystemType" "$TargetPart" "$InstallDir"
if [[ $? != 0 ]] ; then
echo "Couldn't mount $TargetPart ! Aborting!"
rmdir "$InstallDir"
exit 1
fi
fi
} # MountDefaultTarget()
Next, I removed the exit command from the CreateBootCsvFile funtion. Can you explain why this exit command is needed? This would appear to be a bug.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
joevt: Your script has many flaws. Below I outline one main flaw with the mountpartition funciton.
The following line determines if the mount point exists as a directory.
while [ -d"$mountpoint" ]; do
Later, the following line creates the directory.
sudomkdir"$mountpoint"2>/dev/null
Finally, the next line mounts the volume.
sudomount$mounttype"/dev/$slice""$mountpoint"
The problem is the script uses the /Volumes directory. There is no guarantee some other process will not also be accessing the /Volumes directory. In other words, the mountpartition function is not atomic. The diskutil command can do this same operation atomically. However, the diskutil command itself is may not be a solution if you want your script to be compatible with older versions of OS X. For example, I can not find a way to use the diskutil command to mount an EFI partition when booted to Snow Leopard (OS X 10.6.8). I can if using the mount command.
My mac mini has multiple users. Other users are mounting and unmounting independently of what I am doing.
You posted the following :
I use /Volumes so the mount point appears in the Finder desktop automatically.
I am not sure why you made this statement. Perhaps you are using a older version of macOS (OS X). When using High Sierra (macOS 10.13.6) and newer versions of macOS, volumes mounted by using the mount command appear in the Finder automatically regardless of the mount point.
BTW: The variable i in your mountpartition function should be declared local. Also, replace echo -n "$mountpoint" with echo "$mountpoint".
Last edit: David Anderson 2020-10-07
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My script assumes that volumes are not being randomly mounted and unmounted without user interaction (connecting/disconnecting a USB drive, mounting/unmounting a disk image, running an installer script, etc.).
Here is a slightly better implementation (still uses /Volumes for ...reasons...):
mountpartition(){localmounttype=$1localslice=$2localvolume=$3localmountpoint=""mountpoint=$(mount | sed -n -E "/\/dev\/$slice on (.*) \(.*/s//\1/p")if[[ -n "$mountpoint"]];thenecho -n "$mountpoint"return0filocali=0localstartmountpoint="/Volumes/$volume"mountpoint="$startmountpoint"while((1));do
sudo mkdir "$mountpoint"2> /dev/null &&breakif((i++ > 1000));thenecho"Could not create mountpoint"1>&2return1fimountpoint="$startmountpoint$i"done
sudo "mount$mounttype""/dev/$slice""$mountpoint"&&echo -n "$mountpoint"return$?}
It assumes that if a disk is mounted, it will not be unmounted somehow.
It assumes that if it can make the mountpoint directory then some other process is not going to use it before we can use it as a mountpoint.
The improvement here is that we ensure that we are the ones that made the directory by checking the result of mkdir (assuming the directory wasn't deleted and recreated by someone else in the split second before we mount to it).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Your script has many flaws. Below I outline one main flaw.
The following line determines if the mount point exists as a directory.
while [ -d"$mountpoint" ]; do
Later, the following line creates the directory.
sudomkdir"$mountpoint"2>/dev/null
Finally, the next line mounts the volume.
sudomount$mounttype"/dev/$slice""$mountpoint"
The problem is the script uses the /Volumes directory. There is no guarantee some other processes will not also be accessing the /Volumes directory. In other words, the mountpartition function is not atomic. The diskutil command can do this same operation atomically. However, the diskutil command itself is may not be a solution if you want your script to be compatible with older versions of OS X. For example, I can find a way to use the diskutil command to mount an EFI partition when booted to Snow Leopard (OS X 10.6.8). I can if using the mount command.
My mac mini use has multiple users. Other users are mounting and unmounting independently of what I am doing.
BTW: The variable i in your mountpartition function should be declared local. Also, replace echo -n "$mountpoint" with echo "$mountpoint".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
After some thought, I now realize the mount command in the refind-install script prevents the two different users from executing this script simultaneously. We both have been discussing how to install to a volume that is already mounted. Doing so would be a bad idea. So, having to unmount before running the refind-install script is the correct proceedure.
Last edit: David Anderson 2020-10-09
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am trying to install rEFInd to a FAT formatted partition on a 2018 mac mini. The version of rEFInd is 0.12.0. The output from the command
diskutil list disk0
is given below.The command I entered was
sudo ./refind-install --usedefault /dev/disk0s4
. The error messsage wassed: -i may not be used with stdin
. I believe the line in the script causing this messsage is given below.sed -i 's/#showtools shell/showtools install, shell/g' "$InstallDir/$TargetDir/refind.conf"
I made the following correction to get the script to work.
sed -i '' 's/#showtools shell/showtools install, shell/g' "$InstallDir/$TargetDir/refind.conf"
Last edit: David Anderson 2020-10-02
That seems like the correct fix. The fixed code is like this:
The result is like this:
Another change I would make is to allow the EFI partition to already be mounted or not. The code code check if it was mounted, and mount it if it wasn't. InstallDir would point to the mounted location. Here's a function I made to mount a partition and/or get it's mount point location (works in macOS - needs minor changes for Linux):
Then you would call it like this:
where $slice is
disk0s4
in your case. $volume would be whatever you like (refind_install
in the case of the refind script). Maybe replace the part of the code that looks for an unused name in/Volumes
with a temp folder path guaranteed to be unused (usemktemp -d
).The script is not wrong.
sed -i 'XYZ'
is a standard form for sed as implemented on Linux.Apple implemented the "non-standard"
sed -i '' 'XYZ'
form on Macs ... which it seems you are using.Last edit: dakanji 2020-10-02
If the
-i
argument works differently in Linux and macOS, then it needs to be not used, or two different commands need to be included.I encountered a problem where if I ran the command
sudo ./refind-install --usedefault /dev/disk0s4
again after removinginstall
fromshowtools
. Here a message is displayed statingrefind.conf
will not be changed, but is in fact changed. In othe words,install
is again added torefind.conf
. The part of the script where the problem exists is given below.I suggest the following replacement. This replacement also solves the problem with the
-i
option by elimiating the option from thesed
command.Last edit: David Anderson 2020-10-03
I encounter a problem where if I ran the command
sudo ./refind-install --usedefault /dev/disk0s4
again after removinginstall
fromshowtools
. Here a message is displayed statingrefind.conf
will not be changed, but is in fact changed. In othe words,install
is again added torefind.conf
. The part of the script where the problem exist is given below.I suggest the following replacement. This replacement also solves the problem with the
-i
argument.Joevt: I looked an your script to mount a partition. I would not make the mount point in the
/Volumes
folder. Instead, I would keep using the/tmp/refind_install
mount point, when a volumn needs to be mounted. I am not sure why you felt the need to loop until a directory does not exist. Perhaps this is because your script uses the/Volumes
folder?When using the
--usedefault
option, I foundrefind-install
allows installations to mounted volumes after making the following changes.First, I made the change suggested in my previous post.
Next, I replaced the following function in
refind_install
.The new replacement function is given below.
Finally, I removed the
exit
command from theCreateBootCsvFile
funtion. Can you explain why thisexit
command is needed? This would appear to be a bug.Last edit: David Anderson 2020-10-05
I have multiple EFI partitions so I have to loop to make sure my mount point name is unique. See
mountEFIpartitions
at https://gist.github.com/joevt/6d7a0ede45106345a39bdfa0ac10ffd6I could have used the
sudo diskutil mount
command instead. My command is more portable (requires some modification for Linux).diskutil mount
will do what my command does - check if the device is already mounted, and if not, then mount to a new mount point. My command returns "EFI", "EFI1", "EFI2", etc.diskutil
will do "EFI", "EFI 1", "EFI 2", etc. I use/Volumes
so the mount point appears in the Finder desktop automatically.Joevt: I looked an your script to mount a partition. I would not make the mount point in the
/Volumes
folder. Instead, I would keep using the/tmp/refind_install
mount point, when a volumn needs to be mounted. I am not sure why you felt the need to loop until a directory does not exist. Perhaps this is because your script uses the/Volumes
folder?When using the
--usedefault
option, I foundrefind-install
allows installations to mounted volumes after making the following changes.First, I replaced the following function in
refind_install
.The new replacement funciton is given below.
Next, I removed the
exit
command from theCreateBootCsvFile
funtion. Can you explain why thisexit
command is needed? This would appear to be a bug.joevt: Your script has many flaws. Below I outline one main flaw with the
mountpartition
funciton.The following line determines if the mount point exists as a directory.
Later, the following line creates the directory.
Finally, the next line mounts the volume.
The problem is the script uses the
/Volumes
directory. There is no guarantee some other process will not also be accessing the/Volumes
directory. In other words, themountpartition
function is not atomic. Thediskutil
command can do this same operation atomically. However, thediskutil
command itself is may not be a solution if you want your script to be compatible with older versions of OS X. For example, I can not find a way to use thediskutil
command to mount an EFI partition when booted to Snow Leopard (OS X 10.6.8). I can if using themount
command.My mac mini has multiple users. Other users are mounting and unmounting independently of what I am doing.
You posted the following :
I am not sure why you made this statement. Perhaps you are using a older version of macOS (OS X). When using High Sierra (macOS 10.13.6) and newer versions of macOS, volumes mounted by using the
mount
command appear in the Finder automatically regardless of the mount point.BTW: The variable
i
in yourmountpartition
function should be declared local. Also, replaceecho -n "$mountpoint"
withecho "$mountpoint"
.Last edit: David Anderson 2020-10-07
You make valid points.
My script assumes that volumes are not being randomly mounted and unmounted without user interaction (connecting/disconnecting a USB drive, mounting/unmounting a disk image, running an installer script, etc.).
Here is a slightly better implementation (still uses /Volumes for ...reasons...):
It assumes that if a disk is mounted, it will not be unmounted somehow.
It assumes that if it can make the mountpoint directory then some other process is not going to use it before we can use it as a mountpoint.
The improvement here is that we ensure that we are the ones that made the directory by checking the result of mkdir (assuming the directory wasn't deleted and recreated by someone else in the split second before we mount to it).
Your script has many flaws. Below I outline one main flaw.
The following line determines if the mount point exists as a directory.
Later, the following line creates the directory.
Finally, the next line mounts the volume.
The problem is the script uses the
/Volumes
directory. There is no guarantee some other processes will not also be accessing the/Volumes
directory. In other words, themountpartition
function is not atomic. Thediskutil
command can do this same operation atomically. However, thediskutil
command itself is may not be a solution if you want your script to be compatible with older versions of OS X. For example, I can find a way to use thediskutil
command to mount an EFI partition when booted to Snow Leopard (OS X 10.6.8). I can if using themount
command.My mac mini use has multiple users. Other users are mounting and unmounting independently of what I am doing.
BTW: The variable
i
in yourmountpartition
function should be declared local. Also, replaceecho -n "$mountpoint"
withecho "$mountpoint"
.After some thought, I now realize the
mount
command in therefind-install
script prevents the two different users from executing this script simultaneously. We both have been discussing how to install to a volume that is already mounted. Doing so would be a bad idea. So, having to unmount before running therefind-install
script is the correct proceedure.Last edit: David Anderson 2020-10-09