Developer
CHMOD Calculator
Set Unix file permissions visually. Toggle checkboxes or type a numeric code — everything syncs live. Get the ready-to-use chmod command.
Owner
Group
Others
| Entity | Read (r) = 4 | Write (w) = 2 | Execute (x) = 1 |
|---|---|---|---|
u Owner |
|||
g Group |
|||
o Others |
Numeric
755
Symbolic
rwxr-xr-x
Octal
0755
chmod command
chmod 755 filename
recursive (directories)
chmod -R 755 directory/
Owner
7
Read + Write + Execute
Group
5
Read + Execute
Others
5
Read + Execute
644
rw-r--r--
Files
755
rwxr-xr-x
Directories
777
rwxrwxrwx
Full access
600
rw-------
Private
400
r--------
Read-only
700
rwx------
Owner only
664
rw-rw-r--
Group write
775
rwxrwxr-x
Group dir
Developer Reference
Core Algorithm & Standalone Script
Standalone, zero-dependency JavaScript implementation powering this tool. Free to inspect, copy, and build upon.
function clamp(v) { return Math.max(0, Math.min(7, isNaN(v) ? 0 : v)); }
function bitDesc(n) {
const p = [];
if (n & 4) p.push('Read');
if (n & 2) p.push('Write');
if (n & 1) p.push('Execute');
return p.length ? p.join(' + ') : 'No permissions';
}
function toBits(n) {
return (n&4?'r':'-') + (n&2?'w':'-') + (n&1?'x':'-');
}
function updateAll(o, g, oth) {
const num = '' + o + g + oth;
const sym = toBits(o) + toBits(g) + toBits(oth);
document.getElementById('resNum').textContent = num;
document.getElementById('resSym').textContent = sym;
document.getElementById('resOct').textContent = '0' + num;
document.getElementById('cmdN').textContent = num;
document.getElementById('cmdNR').textContent = num;
document.getElementById('bdO').textContent = o;
document.getElementById('bdG').textContent = g;
document.getElementById('bdOth').textContent = oth;
document.getElementById('bdOD').textContent = bitDesc(o);
document.getElementById('bdGD').textContent = bitDesc(g);
document.getElementById('bdOthD').textContent = bitDesc(oth);
}
function setBoxes(o, g, oth) {
document.getElementById('ur').checked = !!(o & 4);
document.getElementById('uw').checked = !!(o & 2);
document.getElementById('ux').checked = !!(o & 1);
document.getElementById('gr').checked = !!(g & 4);
document.getElementById('gw').checked = !!(g & 2);
document.getElementById('gx').checked = !!(g & 1);
document.getElementById('or').checked = !!(oth & 4);
document.getElementById('ow').checked = !!(oth & 2);
document.getElementById('ox').checked = !!(oth & 1);
}
function setDigits(o, g, oth) {
document.getElementById('dO').value = o;
document.getElementById('dG').value = g;
document.getElementById('dOth').value = oth;
}
function syncFromDigits() {
const o = clamp(parseInt(document.getElementById('dO').value));
const g = clamp(parseInt(document.getElementById('dG').value));
const oth = clamp(parseInt(document.getElementById('dOth').value));
setBoxes(o, g, oth);
updateAll(o, g, oth);
}
function syncFromBoxes() {
const o = (document.getElementById('ur').checked?4:0)+(document.getElementById('uw').checked?2:0)+(document.getElementById('ux').checked?1:0);
const g = (document.getElementById('gr').checked?4:0)+(document.getElementById('gw').checked?2:0)+(document.getElementById('gx').checked?1:0);
const oth = (document.getElementById('or').checked?4:0)+(document.getElementById('ow').checked?2:0)+(document.getElementById('ox').checked?1:0);
setDigits(o, g, oth);
updateAll(o, g, oth);
}
function applyPreset(o, g, oth) {
setDigits(o, g, oth);
setBoxes(o, g, oth);
updateAll(o, g, oth);
}
function doCopy(btn, text) {
navigator.clipboard.writeText(text).catch(() => {});
btn.textContent = 'copied!'; btn.classList.add('copied');
setTimeout(() => { btn.textContent = 'copy'; btn.classList.remove('copied'); }, 2000);
}
// Clamp digit inputs on blur and handle arrow keys
['dO','dG','dOth'].forEach(id => {
const el = document.getElementById(id);
el.addEventListener('blur', () => {
el.value = clamp(parseInt(el.value));
syncFromDigits();
});
el.addEventListener('keydown', e => {
if (e.key === 'ArrowUp') { e.preventDefault(); el.value = Math.min(7, parseInt(el.value||0)+1); syncFromDigits(); }
if (e.key === 'ArrowDown') { e.preventDefault(); el.value = Math.max(0, parseInt(el.value||0)-1); syncFromDigits(); }
});
});
// Init
syncFromDigits();