[{"data":1,"prerenderedAt":2368},["ShallowReactive",2],{"doc:\u002Fshells":3},{"id":4,"title":5,"body":6,"description":2362,"extension":2363,"meta":2364,"navigation":317,"path":2365,"seo":2366,"stem":20,"__hash__":2367},"docs\u002Fshells.md","Bash, Zsh y Fish",{"type":7,"value":8,"toc":2341},"minimark",[9,13,22,27,191,213,217,224,260,270,275,278,288,291,510,631,635,638,644,796,799,941,945,1076,1080,1090,1141,1169,1172,1176,1236,1239,1339,1349,1351,1354,1370,1416,1419,1519,1528,1530,1533,1549,1589,1592,1650,1653,1679,1682,1718,1723,1725,1728,1748,1751,1805,1812,1932,1938,1942,1981,1991,1995,1998,2002,2051,2055,2062,2087,2091,2136,2140,2268,2272,2315,2321,2328,2331,2337],[10,11,5],"h1",{"id":12},"bash-zsh-y-fish",[14,15,16,17,21],"p",{},"Los tres son ",[18,19,20],"strong",{},"shells",": programas que leen tus comandos, los interpretan y\npiden al sistema que los ejecute. La diferencia está en cuánto te ayudan, qué\nsintaxis aceptan y qué tan lejos están del estándar.",[23,24,26],"h2",{"id":25},"la-tabla-que-resume-todo","La tabla que resume todo",[28,29,30,54],"table",{},[31,32,33],"thead",{},[34,35,36,39,44,49],"tr",{},[37,38],"th",{},[37,40,41],{},[18,42,43],{},"Bash",[37,45,46],{},[18,47,48],{},"Zsh",[37,50,51],{},[18,52,53],{},"Fish",[55,56,57,72,86,101,115,130,143,157,178],"tbody",{},[34,58,59,63,66,69],{},[60,61,62],"td",{},"Nombre completo",[60,64,65],{},"Bourne Again SHell",[60,67,68],{},"Z shell",[60,70,71],{},"Friendly Interactive SHell",[34,73,74,77,80,83],{},[60,75,76],{},"Dónde viene por defecto",[60,78,79],{},"casi todo Linux",[60,81,82],{},"macOS",[60,84,85],{},"algunos Linux",[34,87,88,91,94,96],{},[60,89,90],{},"Compatible con POSIX",[60,92,93],{},"casi",[60,95,93],{},[60,97,98],{},[18,99,100],{},"no",[34,102,103,106,109,112],{},[60,104,105],{},"Autocompletado",[60,107,108],{},"básico (mejorable)",[60,110,111],{},"muy bueno",[60,113,114],{},"excelente, de fábrica",[34,116,117,120,122,125],{},[60,118,119],{},"Sugerencias mientras escribes",[60,121,100],{},[60,123,124],{},"con plugins",[60,126,127],{},[18,128,129],{},"sí, de fábrica",[34,131,132,135,137,139],{},[60,133,134],{},"Resaltado de sintaxis",[60,136,100],{},[60,138,124],{},[60,140,141],{},[18,142,129],{},[34,144,145,148,151,154],{},[60,146,147],{},"Sintaxis de scripts",[60,149,150],{},"estándar",[60,152,153],{},"estándar + extras",[60,155,156],{},"propia",[34,158,159,162,168,173],{},[60,160,161],{},"Configuración",[60,163,164],{},[165,166,167],"code",{},"~\u002F.bashrc",[60,169,170],{},[165,171,172],{},"~\u002F.zshrc",[60,174,175],{},[165,176,177],{},"~\u002F.config\u002Ffish\u002Fconfig.fish",[34,179,180,183,186,188],{},[60,181,182],{},"Curva de aprendizaje",[60,184,185],{},"media",[60,187,185],{},[60,189,190],{},"baja",[14,192,193,196,197,200,201,204,205,208,209,212],{},[18,194,195],{},"La recomendación práctica",": aprende ",[18,198,199],{},"bash"," para scripting (es lo que vas a\nencontrar en servidores, CI y ejercicios), usa ",[18,202,203],{},"zsh"," o ",[18,206,207],{},"fish"," para el día a\ndía si te gustan, y escribe los scripts siempre en bash o ",[165,210,211],{},"sh",".",[23,214,216],{"id":215},"qué-es-posix-y-cómo-se-estructura-un-script","Qué es POSIX y cómo se estructura un script",[14,218,219,220,223],{},"POSIX no es un programa ni un shell: es un ",[18,221,222],{},"conjunto de normas"," que dice cómo\ndebe comportarse un sistema operativo tipo Unix. Para lo que nos importa, define:",[225,226,227,248,251,254,257],"ul",{},[228,229,230,231,234,235,234,238,234,241,234,244,247],"li",{},"qué comandos tienen que existir (",[165,232,233],{},"cd",", ",[165,236,237],{},"echo",[165,239,240],{},"grep",[165,242,243],{},"sed",[165,245,246],{},"test","…);",[228,249,250],{},"cómo se comporta el shell;",[228,252,253],{},"qué sintaxis tiene el lenguaje de scripting;",[228,255,256],{},"cómo se pasan variables de entorno;",[228,258,259],{},"qué significa el código de salida de un comando.",[14,261,262,263,266,267,212],{},"Si un script dice ",[165,264,265],{},"#!\u002Fbin\u002Fsh"," y usa solo lo que POSIX define, tiene que correr\nigual en Linux, macOS, BSD o un contenedor mínimo. Eso es lo que lo hace\n",[18,268,269],{},"portable",[271,272,274],"h3",{"id":273},"la-estructura-de-un-script-posix","La estructura de un script POSIX",[14,276,277],{},"Un script es un archivo de texto común. Se lee de arriba a abajo, como una\nreceta. El orden habitual es:",[279,280,285],"pre",{"className":281,"code":283,"language":284},[282],"language-text","1. shebang          → con qué programa ejecutarlo\n2. comentarios      → qué hace y cómo se usa\n3. configuración    → opciones del shell\n4. variables        → datos que vas a reutilizar\n5. funciones        → bloques de comandos con nombre\n6. programa         → lo que se ejecuta de verdad\n","text",[165,286,283],{"__ignoreMap":287},"",[14,289,290],{},"Ejemplo mínimo, con cada parte señalada:",[279,292,295],{"className":293,"code":294,"language":211,"meta":287,"style":287},"language-sh shiki shiki-themes github-light github-dark","#!\u002Fbin\u002Fsh\n# compilar.sh: compila un archivo de C y avisa si falta algo.\n\nset -e\n\nsalida=\"programa\"\nfuente=\"$1\"\n\ncompilar() {\n    cc -Wall -Wextra -Werror \"$1\" -o \"$salida\"\n}\n\nif [ -z \"$fuente\" ]; then\n    echo \"Uso: $0 archivo.c\" >&2\n    exit 1\nfi\n\ncompilar \"$fuente\"\necho \"Listo: $salida\"\n",[165,296,297,306,312,319,329,334,349,366,371,381,413,419,424,449,467,476,482,487,498],{"__ignoreMap":287},[298,299,302],"span",{"class":300,"line":301},"line",1,[298,303,305],{"class":304},"sJ8bj","#!\u002Fbin\u002Fsh\n",[298,307,309],{"class":300,"line":308},2,[298,310,311],{"class":304},"# compilar.sh: compila un archivo de C y avisa si falta algo.\n",[298,313,315],{"class":300,"line":314},3,[298,316,318],{"emptyLinePlaceholder":317},true,"\n",[298,320,322,326],{"class":300,"line":321},4,[298,323,325],{"class":324},"sj4cs","set",[298,327,328],{"class":324}," -e\n",[298,330,332],{"class":300,"line":331},5,[298,333,318],{"emptyLinePlaceholder":317},[298,335,337,341,345],{"class":300,"line":336},6,[298,338,340],{"class":339},"sVt8B","salida",[298,342,344],{"class":343},"szBVR","=",[298,346,348],{"class":347},"sZZnC","\"programa\"\n",[298,350,352,355,357,360,363],{"class":300,"line":351},7,[298,353,354],{"class":339},"fuente",[298,356,344],{"class":343},[298,358,359],{"class":347},"\"",[298,361,362],{"class":324},"$1",[298,364,365],{"class":347},"\"\n",[298,367,369],{"class":300,"line":368},8,[298,370,318],{"emptyLinePlaceholder":317},[298,372,374,378],{"class":300,"line":373},9,[298,375,377],{"class":376},"sScJk","compilar",[298,379,380],{"class":339},"() {\n",[298,382,384,387,390,393,396,399,401,403,406,408,411],{"class":300,"line":383},10,[298,385,386],{"class":376},"    cc",[298,388,389],{"class":324}," -Wall",[298,391,392],{"class":324}," -Wextra",[298,394,395],{"class":324}," -Werror",[298,397,398],{"class":347}," \"",[298,400,362],{"class":324},[298,402,359],{"class":347},[298,404,405],{"class":324}," -o",[298,407,398],{"class":347},[298,409,410],{"class":339},"$salida",[298,412,365],{"class":347},[298,414,416],{"class":300,"line":415},11,[298,417,418],{"class":339},"}\n",[298,420,422],{"class":300,"line":421},12,[298,423,318],{"emptyLinePlaceholder":317},[298,425,427,430,433,436,438,441,443,446],{"class":300,"line":426},13,[298,428,429],{"class":343},"if",[298,431,432],{"class":339}," [ ",[298,434,435],{"class":343},"-z",[298,437,398],{"class":347},[298,439,440],{"class":339},"$fuente",[298,442,359],{"class":347},[298,444,445],{"class":339}," ]; ",[298,447,448],{"class":343},"then\n",[298,450,452,455,458,461,464],{"class":300,"line":451},14,[298,453,454],{"class":324},"    echo",[298,456,457],{"class":347}," \"Uso: ",[298,459,460],{"class":324},"$0",[298,462,463],{"class":347}," archivo.c\"",[298,465,466],{"class":343}," >&2\n",[298,468,470,473],{"class":300,"line":469},15,[298,471,472],{"class":324},"    exit",[298,474,475],{"class":324}," 1\n",[298,477,479],{"class":300,"line":478},16,[298,480,481],{"class":343},"fi\n",[298,483,485],{"class":300,"line":484},17,[298,486,318],{"emptyLinePlaceholder":317},[298,488,490,492,494,496],{"class":300,"line":489},18,[298,491,377],{"class":376},[298,493,398],{"class":347},[298,495,440],{"class":339},[298,497,365],{"class":347},[298,499,501,503,506,508],{"class":300,"line":500},19,[298,502,237],{"class":324},[298,504,505],{"class":347}," \"Listo: ",[298,507,410],{"class":339},[298,509,365],{"class":347},[28,511,512,522],{},[31,513,514],{},[34,515,516,519],{},[37,517,518],{},"Línea",[37,520,521],{},"Qué hace",[55,523,524,540,553,563,579,591,601,611,621],{},[34,525,526,530],{},[60,527,528],{},[165,529,265],{},[60,531,532,533,536,537,539],{},"el ",[18,534,535],{},"shebang",": indica que lo ejecute ",[165,538,211],{},". Va en la primera línea, sin espacios antes.",[34,541,542,547],{},[60,543,544],{},[165,545,546],{},"# ...",[60,548,549,550,212],{},"comentario: el shell lo ignora. Sirve para explicar el ",[18,551,552],{},"por qué",[34,554,555,560],{},[60,556,557],{},[165,558,559],{},"set -e",[60,561,562],{},"si un comando falla, el script corta. Evita seguir con datos rotos.",[34,564,565,570],{},[60,566,567],{},[165,568,569],{},"salida=\"programa\"",[60,571,572,573,576,577,212],{},"variable. ",[18,574,575],{},"No"," lleva espacios alrededor del ",[165,578,344],{},[34,580,581,586],{},[60,582,583],{},[165,584,585],{},"fuente=\"$1\"",[60,587,588,590],{},[165,589,362],{}," es el primer argumento que recibe el script.",[34,592,593,598],{},[60,594,595],{},[165,596,597],{},"compilar() { ... }",[60,599,600],{},"función: un bloque de comandos con nombre.",[34,602,603,608],{},[60,604,605],{},[165,606,607],{},"[ -z \"$fuente\" ]",[60,609,610],{},"prueba POSIX: verdadera si la cadena está vacía.",[34,612,613,618],{},[60,614,615],{},[165,616,617],{},">&2",[60,619,620],{},"manda el mensaje al canal de errores.",[34,622,623,628],{},[60,624,625],{},[165,626,627],{},"exit 1",[60,629,630],{},"termina con código de error (0 significa \"salió bien\").",[271,632,634],{"id":633},"la-gramática-de-una-línea","La gramática de una línea",[14,636,637],{},"Casi todo comando sigue esta forma:",[279,639,642],{"className":640,"code":641,"language":284},[282],"comando [opciones] [argumentos] [redirecciones]\n",[165,643,641],{"__ignoreMap":287},[279,645,647],{"className":293,"code":646,"language":211,"meta":287,"style":287},"grep   -rn   \"TODO\"   src\u002F   > pendientes.txt\n│      │     │        │      │\n│      │     │        │      └─ redirección: guarda la salida en un archivo\n│      │     │        └──────── argumento: dónde buscar\n│      │     └───────────────── argumento: qué buscar\n│      └─────────────────────── opciones: modifican el comportamiento\n└────────────────────────────── comando: el programa que se ejecuta\n",[165,648,649,668,685,719,739,755,774],{"__ignoreMap":287},[298,650,651,653,656,659,662,665],{"class":300,"line":301},[298,652,240],{"class":376},[298,654,655],{"class":324},"   -rn",[298,657,658],{"class":347},"   \"TODO\"",[298,660,661],{"class":347},"   src\u002F",[298,663,664],{"class":343},"   >",[298,666,667],{"class":347}," pendientes.txt\n",[298,669,670,673,676,679,682],{"class":300,"line":308},[298,671,672],{"class":376},"│",[298,674,675],{"class":347},"      │",[298,677,678],{"class":347},"     │",[298,680,681],{"class":347},"        │",[298,683,684],{"class":347},"      │\n",[298,686,687,689,691,693,695,698,701,704,707,710,713,716],{"class":300,"line":314},[298,688,672],{"class":376},[298,690,675],{"class":347},[298,692,678],{"class":347},[298,694,681],{"class":347},[298,696,697],{"class":347},"      └─",[298,699,700],{"class":347}," redirección:",[298,702,703],{"class":347}," guarda",[298,705,706],{"class":347}," la",[298,708,709],{"class":347}," salida",[298,711,712],{"class":347}," en",[298,714,715],{"class":347}," un",[298,717,718],{"class":347}," archivo\n",[298,720,721,723,725,727,730,733,736],{"class":300,"line":321},[298,722,672],{"class":376},[298,724,675],{"class":347},[298,726,678],{"class":347},[298,728,729],{"class":347},"        └────────",[298,731,732],{"class":347}," argumento:",[298,734,735],{"class":347}," dónde",[298,737,738],{"class":347}," buscar\n",[298,740,741,743,745,748,750,753],{"class":300,"line":331},[298,742,672],{"class":376},[298,744,675],{"class":347},[298,746,747],{"class":347},"     └─────────────────",[298,749,732],{"class":347},[298,751,752],{"class":347}," qué",[298,754,738],{"class":347},[298,756,757,759,762,765,768,771],{"class":300,"line":336},[298,758,672],{"class":376},[298,760,761],{"class":347},"      └───────────────────────",[298,763,764],{"class":347}," opciones:",[298,766,767],{"class":347}," modifican",[298,769,770],{"class":347}," el",[298,772,773],{"class":347}," comportamiento\n",[298,775,776,779,782,784,787,790,793],{"class":300,"line":351},[298,777,778],{"class":376},"└──────────────────────────────",[298,780,781],{"class":347}," comando:",[298,783,770],{"class":347},[298,785,786],{"class":347}," programa",[298,788,789],{"class":347}," que",[298,791,792],{"class":347}," se",[298,794,795],{"class":347}," ejecuta\n",[14,797,798],{},"Los operadores que combinan comandos son parte del lenguaje:",[28,800,801,813],{},[31,802,803],{},[34,804,805,808,810],{},[37,806,807],{},"Operador",[37,809,521],{},[37,811,812],{},"Ejemplo",[55,814,815,830,845,860,875,890,905,924],{},[34,816,817,822,825],{},[60,818,819],{},[165,820,821],{},"|",[60,823,824],{},"conecta la salida de uno con la entrada del otro",[60,826,827],{},[165,828,829],{},"ls | wc -l",[34,831,832,837,840],{},[60,833,834],{},[165,835,836],{},">",[60,838,839],{},"guarda la salida en un archivo (lo pisa)",[60,841,842],{},[165,843,844],{},"echo hola > saludo.txt",[34,846,847,852,855],{},[60,848,849],{},[165,850,851],{},">>",[60,853,854],{},"agrega al final del archivo",[60,856,857],{},[165,858,859],{},"echo otra >> saludo.txt",[34,861,862,867,870],{},[60,863,864],{},[165,865,866],{},"\u003C",[60,868,869],{},"toma la entrada desde un archivo",[60,871,872],{},[165,873,874],{},"wc -l \u003C lista.txt",[34,876,877,882,885],{},[60,878,879],{},[165,880,881],{},"2>",[60,883,884],{},"redirige solo los errores",[60,886,887],{},[165,888,889],{},"cmd 2> errores.txt",[34,891,892,897,900],{},[60,893,894],{},[165,895,896],{},";",[60,898,899],{},"ejecuta uno y después el otro, pase lo que pase",[60,901,902],{},[165,903,904],{},"cd \u002Ftmp; ls",[34,906,907,912,919],{},[60,908,909],{},[165,910,911],{},"&&",[60,913,914,915,918],{},"ejecuta el segundo ",[18,916,917],{},"solo si"," el primero salió bien",[60,920,921],{},[165,922,923],{},"gcc main.c && .\u002Fa.out",[34,925,926,931,936],{},[60,927,928],{},[165,929,930],{},"||",[60,932,914,933,935],{},[18,934,917],{}," el primero falló",[60,937,938],{},[165,939,940],{},"cd carpeta || exit 1",[271,942,944],{"id":943},"las-piezas-del-lenguaje","Las piezas del lenguaje",[28,946,947,960],{},[31,948,949],{},[34,950,951,954,957],{},[37,952,953],{},"Pieza",[37,955,956],{},"Cómo se escribe",[37,958,959],{},"Para qué",[55,961,962,975,988,1006,1019,1032,1045,1058],{},[34,963,964,967,972],{},[60,965,966],{},"variable",[60,968,969],{},[165,970,971],{},"nombre=\"valor\"",[60,973,974],{},"guardar un dato",[34,976,977,980,985],{},[60,978,979],{},"usar variable",[60,981,982],{},[165,983,984],{},"\"$nombre\"",[60,986,987],{},"leerlo (siempre entre comillas)",[34,989,990,993,1003],{},[60,991,992],{},"argumento",[60,994,995,234,997,234,1000],{},[165,996,362],{},[165,998,999],{},"$2",[165,1001,1002],{},"$#",[60,1004,1005],{},"lo que recibe el script",[34,1007,1008,1011,1016],{},[60,1009,1010],{},"condición",[60,1012,1013],{},[165,1014,1015],{},"if [ ... ]; then ... fi",[60,1017,1018],{},"decidir",[34,1020,1021,1024,1029],{},[60,1022,1023],{},"bucle",[60,1025,1026],{},[165,1027,1028],{},"for x in ...; do ... done",[60,1030,1031],{},"repetir",[34,1033,1034,1037,1042],{},[60,1035,1036],{},"bucle condicional",[60,1038,1039],{},[165,1040,1041],{},"while [ ... ]; do ... done",[60,1043,1044],{},"repetir mientras",[34,1046,1047,1050,1055],{},[60,1048,1049],{},"función",[60,1051,1052],{},[165,1053,1054],{},"nombre() { ... }",[60,1056,1057],{},"agrupar comandos y reutilizarlos",[34,1059,1060,1063,1073],{},[60,1061,1062],{},"código de salida",[60,1064,1065,234,1068,234,1071],{},[165,1066,1067],{},"$?",[165,1069,1070],{},"exit 0",[165,1072,627],{},[60,1074,1075],{},"decir si salió bien o mal",[271,1077,1079],{"id":1078},"qué-es-una-función-y-por-qué-aparece-en-todos-lados","Qué es una función (y por qué aparece en todos lados)",[14,1081,1082,1083,1085,1086,1089],{},"Una ",[18,1084,1049],{}," es un ",[18,1087,1088],{},"bloque de comandos con un nombre",". En vez de repetir\nlas mismas cinco líneas en tres lugares, las escribes una vez y las llamas por\nsu nombre. Eso es todo.",[279,1091,1093],{"className":293,"code":1092,"language":211,"meta":287,"style":287},"saludar() {\n    echo \"Hola, $1\"\n}\n\nsaludar \"Ana\"     # imprime: Hola, Ana\nsaludar \"Luis\"    # imprime: Hola, Luis\n",[165,1094,1095,1102,1113,1117,1121,1131],{"__ignoreMap":287},[298,1096,1097,1100],{"class":300,"line":301},[298,1098,1099],{"class":376},"saludar",[298,1101,380],{"class":339},[298,1103,1104,1106,1109,1111],{"class":300,"line":308},[298,1105,454],{"class":324},[298,1107,1108],{"class":347}," \"Hola, ",[298,1110,362],{"class":324},[298,1112,365],{"class":347},[298,1114,1115],{"class":300,"line":314},[298,1116,418],{"class":339},[298,1118,1119],{"class":300,"line":321},[298,1120,318],{"emptyLinePlaceholder":317},[298,1122,1123,1125,1128],{"class":300,"line":331},[298,1124,1099],{"class":376},[298,1126,1127],{"class":347}," \"Ana\"",[298,1129,1130],{"class":304},"     # imprime: Hola, Ana\n",[298,1132,1133,1135,1138],{"class":300,"line":336},[298,1134,1099],{"class":376},[298,1136,1137],{"class":347}," \"Luis\"",[298,1139,1140],{"class":304},"    # imprime: Hola, Luis\n",[225,1142,1143,1148,1153,1163],{},[228,1144,1145,1147],{},[165,1146,1099],{}," es el nombre.",[228,1149,1150,1152],{},[165,1151,362],{}," es el primer argumento que recibe la función.",[228,1154,1155,1156,1159,1160,212],{},"El cuerpo va entre ",[165,1157,1158],{},"{"," y ",[165,1161,1162],{},"}",[228,1164,1165,1168],{},[165,1166,1167],{},"local nombre=\"$1\""," (en bash) hace que la variable no se escape de la función.",[14,1170,1171],{},"La misma idea existe en C, en Python y en casi todos los lenguajes: un bloque de\ncódigo con nombre que puedes ejecutar cuando quieras. En los scripts sirve para\nno repetir y para que el script se lea como una lista de pasos.",[271,1173,1175],{"id":1174},"posix-vs-bash","POSIX vs bash",[28,1177,1178,1191],{},[31,1179,1180],{},[34,1181,1182,1185,1188],{},[37,1183,1184],{},"Shell",[37,1186,1187],{},"¿Es POSIX?",[37,1189,1190],{},"Consecuencia",[55,1192,1193,1206,1216,1225],{},[34,1194,1195,1200,1203],{},[60,1196,1197,1199],{},[165,1198,211],{}," (dash en Debian\u002FUbuntu)",[60,1201,1202],{},"sí",[60,1204,1205],{},"mínimo común denominador",[34,1207,1208,1210,1213],{},[60,1209,199],{},[60,1211,1212],{},"casi (tiene extensiones)",[60,1214,1215],{},"seguro en casi todos lados",[34,1217,1218,1220,1222],{},[60,1219,203],{},[60,1221,93],{},[60,1223,1224],{},"acepta lo de bash, con variantes",[34,1226,1227,1229,1233],{},[60,1228,207],{},[60,1230,1231],{},[18,1232,100],{},[60,1234,1235],{},"un script de fish no corre en bash, ni al revés",[14,1237,1238],{},"Diferencias que te van a morder:",[28,1240,1241,1257],{},[31,1242,1243],{},[34,1244,1245,1248,1254],{},[37,1246,1247],{},"Quieres",[37,1249,1250,1251,1253],{},"POSIX (",[165,1252,211],{},")",[37,1255,1256],{},"bash \u002F zsh",[55,1258,1259,1274,1289,1302,1313,1325],{},[34,1260,1261,1264,1269],{},[60,1262,1263],{},"comparar cadenas",[60,1265,1266],{},[165,1267,1268],{},"[ \"$a\" = \"$b\" ]",[60,1270,1271],{},[165,1272,1273],{},"[[ \"$a\" == \"$b\" ]]",[34,1275,1276,1279,1284],{},[60,1277,1278],{},"condición combinada",[60,1280,1281],{},[165,1282,1283],{},"[ -f x ] && [ -r x ]",[60,1285,1286],{},[165,1287,1288],{},"[[ -f x && -r x ]]",[34,1290,1291,1294,1297],{},[60,1292,1293],{},"arrays",[60,1295,1296],{},"no tiene",[60,1298,1299],{},[165,1300,1301],{},"frutas=(manzana pera)",[34,1303,1304,1309,1311],{},[60,1305,1306],{},[165,1307,1308],{},"$(...)",[60,1310,1202],{},[60,1312,1202],{},[34,1314,1315,1320,1323],{},[60,1316,1317],{},[165,1318,1319],{},"local",[60,1321,1322],{},"no estándar",[60,1324,1202],{},[34,1326,1327,1332,1334],{},[60,1328,1329],{},[165,1330,1331],{},"pipefail",[60,1333,100],{},[60,1335,1336],{},[165,1337,1338],{},"set -o pipefail",[14,1340,1341,1342,1344,1345,1348],{},"Regla: si el script va a correr en otro lado, ",[165,1343,265],{}," con sintaxis POSIX, o\n",[165,1346,1347],{},"#!\u002Fusr\u002Fbin\u002Fenv bash"," si necesitas las extensiones de bash. Fish es para tu\nterminal, no para scripts portables.",[23,1350,43],{"id":199},[14,1352,1353],{},"El que vas a encontrar en el 95 % de los servidores Linux.",[279,1355,1357],{"className":293,"code":1356,"language":211,"meta":287,"style":287},"echo \"$BASH_VERSION\"\n",[165,1358,1359],{"__ignoreMap":287},[298,1360,1361,1363,1365,1368],{"class":300,"line":301},[298,1362,237],{"class":324},[298,1364,398],{"class":347},[298,1366,1367],{"class":339},"$BASH_VERSION",[298,1369,365],{"class":347},[28,1371,1372,1382],{},[31,1373,1374],{},[34,1375,1376,1379],{},[37,1377,1378],{},"Archivo",[37,1380,1381],{},"Cuándo se carga",[55,1383,1384,1393,1403],{},[34,1385,1386,1390],{},[60,1387,1388],{},[165,1389,167],{},[60,1391,1392],{},"cada terminal interactiva (lo más común)",[34,1394,1395,1400],{},[60,1396,1397],{},[165,1398,1399],{},"~\u002F.bash_profile",[60,1401,1402],{},"al iniciar sesión",[34,1404,1405,1410],{},[60,1406,1407],{},[165,1408,1409],{},"~\u002F.profile",[60,1411,1412,1413],{},"login, si no existe ",[165,1414,1415],{},".bash_profile",[14,1417,1418],{},"Cosas que sabe hacer:",[279,1420,1423],{"className":1421,"code":1422,"language":199,"meta":287,"style":287},"language-bash shiki shiki-themes github-light github-dark","frutas=(\"manzana\" \"pera\")       # arrays, índice 0\necho \"${frutas[0]}\"             # manzana\n[[ -f archivo && -r archivo ]]  # condiciones combinadas\nfor f in *.c; do echo \"$f\"; done\n",[165,1424,1425,1447,1462,1484],{"__ignoreMap":287},[298,1426,1427,1430,1432,1435,1438,1441,1444],{"class":300,"line":301},[298,1428,1429],{"class":339},"frutas",[298,1431,344],{"class":343},[298,1433,1434],{"class":339},"(",[298,1436,1437],{"class":347},"\"manzana\"",[298,1439,1440],{"class":347}," \"pera\"",[298,1442,1443],{"class":339},")       ",[298,1445,1446],{"class":304},"# arrays, índice 0\n",[298,1448,1449,1451,1454,1456,1459],{"class":300,"line":308},[298,1450,237],{"class":324},[298,1452,1453],{"class":347}," \"${",[298,1455,1429],{"class":339},[298,1457,1458],{"class":347},"[0]}\"",[298,1460,1461],{"class":304},"             # manzana\n",[298,1463,1464,1467,1470,1473,1475,1478,1481],{"class":300,"line":314},[298,1465,1466],{"class":339},"[[ ",[298,1468,1469],{"class":343},"-f",[298,1471,1472],{"class":339}," archivo ",[298,1474,911],{"class":343},[298,1476,1477],{"class":343}," -r",[298,1479,1480],{"class":339}," archivo ]]  ",[298,1482,1483],{"class":304},"# condiciones combinadas\n",[298,1485,1486,1489,1492,1495,1498,1501,1504,1507,1509,1512,1514,1516],{"class":300,"line":321},[298,1487,1488],{"class":343},"for",[298,1490,1491],{"class":339}," f ",[298,1493,1494],{"class":343},"in",[298,1496,1497],{"class":347}," *.c",[298,1499,1500],{"class":339},"; ",[298,1502,1503],{"class":343},"do",[298,1505,1506],{"class":324}," echo",[298,1508,398],{"class":347},[298,1510,1511],{"class":339},"$f",[298,1513,359],{"class":347},[298,1515,1500],{"class":339},[298,1517,1518],{"class":343},"done\n",[14,1520,1521,1522,1527],{},"Es el shell de referencia para scripting: todo lo del documento de\n",[1523,1524,1526],"a",{"href":1525},"\u002Fterminal","terminal"," aplica aquí.",[23,1529,48],{"id":203},[14,1531,1532],{},"Nació como una mejora de bash. Es el shell por defecto de macOS desde 2019.",[279,1534,1536],{"className":293,"code":1535,"language":211,"meta":287,"style":287},"echo \"$ZSH_VERSION\"\n",[165,1537,1538],{"__ignoreMap":287},[298,1539,1540,1542,1544,1547],{"class":300,"line":301},[298,1541,237],{"class":324},[298,1543,398],{"class":347},[298,1545,1546],{"class":339},"$ZSH_VERSION",[298,1548,365],{"class":347},[28,1550,1551,1559],{},[31,1552,1553],{},[34,1554,1555,1557],{},[37,1556,1378],{},[37,1558,1381],{},[55,1560,1561,1571,1580],{},[34,1562,1563,1568],{},[60,1564,1565],{},[165,1566,1567],{},"~\u002F.zshenv",[60,1569,1570],{},"siempre",[34,1572,1573,1577],{},[60,1574,1575],{},[165,1576,172],{},[60,1578,1579],{},"cada terminal interactiva",[34,1581,1582,1587],{},[60,1583,1584],{},[165,1585,1586],{},"~\u002F.zprofile",[60,1588,1402],{},[14,1590,1591],{},"Lo que gana sobre bash:",[28,1593,1594,1603],{},[31,1595,1596],{},[34,1597,1598,1601],{},[37,1599,1600],{},"Función",[37,1602,812],{},[55,1604,1605,1613,1624,1634,1642],{},[34,1606,1607,1610],{},[60,1608,1609],{},"Autocompletado potente",[60,1611,1612],{},"Tab cicla opciones con descripción",[34,1614,1615,1618],{},[60,1616,1617],{},"Globbing extendido",[60,1619,1620,1623],{},[165,1621,1622],{},"ls **\u002F*.c"," recursivo",[34,1625,1626,1629],{},[60,1627,1628],{},"Corrección de typos",[60,1630,1631],{},[165,1632,1633],{},"setopt correct",[34,1635,1636,1639],{},[60,1637,1638],{},"Temas y plugins",[60,1640,1641],{},"oh-my-zsh, zinit, antidote",[34,1643,1644,1647],{},[60,1645,1646],{},"Prompt a medida",[60,1648,1649],{},"powerlevel10k, starship",[14,1651,1652],{},"Detalles que sorprenden:",[225,1654,1655,1666,1672],{},[228,1656,1657,1658,1661,1662,1665],{},"Los arrays empiezan en ",[18,1659,1660],{},"1",", no en 0: ",[165,1663,1664],{},"${array[1]}"," es el primero.",[228,1667,1668,1671],{},[165,1669,1670],{},"**\u002F"," recursivo viene activado.",[228,1673,1674,1675,1678],{},"Con ",[165,1676,1677],{},"setopt"," cambias comportamientos que en bash son fijos.",[14,1680,1681],{},"Instalación típica (Ubuntu\u002FDebian):",[279,1683,1685],{"className":293,"code":1684,"language":211,"meta":287,"style":287},"sudo apt install zsh\nchsh -s \"$(which zsh)\"\n",[165,1686,1687,1701],{"__ignoreMap":287},[298,1688,1689,1692,1695,1698],{"class":300,"line":301},[298,1690,1691],{"class":376},"sudo",[298,1693,1694],{"class":347}," apt",[298,1696,1697],{"class":347}," install",[298,1699,1700],{"class":347}," zsh\n",[298,1702,1703,1706,1709,1712,1715],{"class":300,"line":308},[298,1704,1705],{"class":376},"chsh",[298,1707,1708],{"class":324}," -s",[298,1710,1711],{"class":347}," \"$(",[298,1713,1714],{"class":324},"which",[298,1716,1717],{"class":347}," zsh)\"\n",[14,1719,1720,1721,212],{},"Cierra sesión y vuelve a entrar. Para probar sin cambiar nada: ",[165,1722,203],{},[23,1724,53],{"id":207},[14,1726,1727],{},"Está diseñado para ser cómodo sin configurar nada.",[279,1729,1731],{"className":293,"code":1730,"language":211,"meta":287,"style":287},"echo $FISH_VERSION\nfish_config    # abre la configuración en el navegador\n",[165,1732,1733,1740],{"__ignoreMap":287},[298,1734,1735,1737],{"class":300,"line":301},[298,1736,237],{"class":324},[298,1738,1739],{"class":339}," $FISH_VERSION\n",[298,1741,1742,1745],{"class":300,"line":308},[298,1743,1744],{"class":376},"fish_config",[298,1746,1747],{"class":304},"    # abre la configuración en el navegador\n",[14,1749,1750],{},"Lo que trae de fábrica:",[28,1752,1753,1762],{},[31,1754,1755],{},[34,1756,1757,1759],{},[37,1758,1600],{},[37,1760,1761],{},"Cómo se ve",[55,1763,1764,1772,1780,1787,1795],{},[34,1765,1766,1769],{},[60,1767,1768],{},"Sugerencias",[60,1770,1771],{},"gris claro con el resto del comando anterior",[34,1773,1774,1777],{},[60,1775,1776],{},"Resaltado",[60,1778,1779],{},"verde si el comando existe, rojo si no",[34,1781,1782,1784],{},[60,1783,105],{},[60,1785,1786],{},"con descripciones y pestañas",[34,1788,1789,1792],{},[60,1790,1791],{},"Historial compartido",[60,1793,1794],{},"entre terminales, al instante",[34,1796,1797,1800],{},[60,1798,1799],{},"Funciones con nombre",[60,1801,1802],{},[165,1803,1804],{},"function saludo ... end",[14,1806,1807,1808,1811],{},"El costo: ",[18,1809,1810],{},"sintaxis propia",". No es POSIX.",[28,1813,1814,1825],{},[31,1815,1816],{},[34,1817,1818,1820,1823],{},[37,1819,1247],{},[37,1821,1822],{},"Bash \u002F Zsh",[37,1824,53],{},[55,1826,1827,1842,1857,1872,1886,1904,1918],{},[34,1828,1829,1832,1837],{},[60,1830,1831],{},"asignar variable",[60,1833,1834],{},[165,1835,1836],{},"VAR=\"hola\"",[60,1838,1839],{},[165,1840,1841],{},"set VAR hola",[34,1843,1844,1847,1852],{},[60,1845,1846],{},"exportar",[60,1848,1849],{},[165,1850,1851],{},"export VAR=hola",[60,1853,1854],{},[165,1855,1856],{},"set -gx VAR hola",[34,1858,1859,1862,1867],{},[60,1860,1861],{},"capturar salida",[60,1863,1864],{},[165,1865,1866],{},"$(comando)",[60,1868,1869],{},[165,1870,1871],{},"(comando)",[34,1873,1874,1877,1881],{},[60,1875,1876],{},"si falló",[60,1878,1879],{},[165,1880,1067],{},[60,1882,1883],{},[165,1884,1885],{},"$status",[34,1887,1888,1891,1895],{},[60,1889,1890],{},"Y lógico",[60,1892,1893],{},[165,1894,911],{},[60,1896,1897,1900,1901,1903],{},[165,1898,1899],{},"and"," (o ",[165,1902,911],{}," moderno)",[34,1905,1906,1908,1913],{},[60,1907,1049],{},[60,1909,1910],{},[165,1911,1912],{},"f() { ... }",[60,1914,1915],{},[165,1916,1917],{},"function f; ...; end",[34,1919,1920,1922,1927],{},[60,1921,1010],{},[60,1923,1924],{},[165,1925,1926],{},"[[ -f x ]]",[60,1928,1929],{},[165,1930,1931],{},"test -f x",[14,1933,1934,1935,212],{},"Por eso: ",[18,1936,1937],{},"fish para la terminal, bash para los scripts",[23,1939,1941],{"id":1940},"cómo-cambiar-de-shell","Cómo cambiar de shell",[279,1943,1945],{"className":293,"code":1944,"language":211,"meta":287,"style":287},"cat \u002Fetc\u002Fshells              # shells permitidos en el sistema\nchsh -s \u002Fusr\u002Fbin\u002Fzsh         # cambia tu shell por defecto\nexec zsh                     # prueba sin cerrar la sesión\n",[165,1946,1947,1958,1970],{"__ignoreMap":287},[298,1948,1949,1952,1955],{"class":300,"line":301},[298,1950,1951],{"class":376},"cat",[298,1953,1954],{"class":347}," \u002Fetc\u002Fshells",[298,1956,1957],{"class":304},"              # shells permitidos en el sistema\n",[298,1959,1960,1962,1964,1967],{"class":300,"line":308},[298,1961,1705],{"class":376},[298,1963,1708],{"class":324},[298,1965,1966],{"class":347}," \u002Fusr\u002Fbin\u002Fzsh",[298,1968,1969],{"class":304},"         # cambia tu shell por defecto\n",[298,1971,1972,1975,1978],{"class":300,"line":314},[298,1973,1974],{"class":324},"exec",[298,1976,1977],{"class":347}," zsh",[298,1979,1980],{"class":304},"                     # prueba sin cerrar la sesión\n",[14,1982,1983,1984,1986,1987,1990],{},"Si ",[165,1985,1705],{}," dice que el shell no está en ",[165,1988,1989],{},"\u002Fetc\u002Fshells",", hay que agregarlo (con\npermisos de administrador) o instalar el paquete que lo provee.",[23,1992,1994],{"id":1993},"configuración-que-sí-vale-la-pena","Configuración que sí vale la pena",[14,1996,1997],{},"Sin importar el shell, tres cosas mejoran el día a día:",[271,1999,2001],{"id":2000},"_1-alias","1. Alias",[279,2003,2005],{"className":293,"code":2004,"language":211,"meta":287,"style":287},"alias ll=\"ls -la\"\nalias g=\"git\"\nalias gs=\"git status\"\nalias ..=\"cd ..\"\n",[165,2006,2007,2020,2032,2044],{"__ignoreMap":287},[298,2008,2009,2012,2015,2017],{"class":300,"line":301},[298,2010,2011],{"class":343},"alias",[298,2013,2014],{"class":339}," ll",[298,2016,344],{"class":343},[298,2018,2019],{"class":347},"\"ls -la\"\n",[298,2021,2022,2024,2027,2029],{"class":300,"line":308},[298,2023,2011],{"class":343},[298,2025,2026],{"class":339}," g",[298,2028,344],{"class":343},[298,2030,2031],{"class":347},"\"git\"\n",[298,2033,2034,2036,2039,2041],{"class":300,"line":314},[298,2035,2011],{"class":343},[298,2037,2038],{"class":339}," gs",[298,2040,344],{"class":343},[298,2042,2043],{"class":347},"\"git status\"\n",[298,2045,2046,2048],{"class":300,"line":321},[298,2047,2011],{"class":324},[298,2049,2050],{"class":347}," ..=\"cd ..\"\n",[271,2052,2054],{"id":2053},"_2-prompt-informativo","2. Prompt informativo",[14,2056,2057,2058,2061],{},"Un buen prompt te dice en qué carpeta estás, si hay cambios sin commitear y qué\nrama tienes. ",[165,2059,2060],{},"starship"," funciona en los tres shells:",[279,2063,2065],{"className":293,"code":2064,"language":211,"meta":287,"style":287},"# ~\u002F.bashrc o ~\u002F.zshrc\neval \"$(starship init bash)\"   # o zsh\n",[165,2066,2067,2072],{"__ignoreMap":287},[298,2068,2069],{"class":300,"line":301},[298,2070,2071],{"class":304},"# ~\u002F.bashrc o ~\u002F.zshrc\n",[298,2073,2074,2077,2079,2081,2084],{"class":300,"line":308},[298,2075,2076],{"class":324},"eval",[298,2078,1711],{"class":347},[298,2080,2060],{"class":376},[298,2082,2083],{"class":347}," init bash)\"",[298,2085,2086],{"class":304},"   # o zsh\n",[271,2088,2090],{"id":2089},"_3-historial-compartido","3. Historial compartido",[279,2092,2094],{"className":293,"code":2093,"language":211,"meta":287,"style":287},"# bash: ~\u002F.bashrc\nshopt -s histappend\nexport HISTSIZE=10000\nexport HISTFILESIZE=20000\n",[165,2095,2096,2101,2111,2124],{"__ignoreMap":287},[298,2097,2098],{"class":300,"line":301},[298,2099,2100],{"class":304},"# bash: ~\u002F.bashrc\n",[298,2102,2103,2106,2108],{"class":300,"line":308},[298,2104,2105],{"class":376},"shopt",[298,2107,1708],{"class":324},[298,2109,2110],{"class":347}," histappend\n",[298,2112,2113,2116,2119,2121],{"class":300,"line":314},[298,2114,2115],{"class":343},"export",[298,2117,2118],{"class":339}," HISTSIZE",[298,2120,344],{"class":343},[298,2122,2123],{"class":324},"10000\n",[298,2125,2126,2128,2131,2133],{"class":300,"line":321},[298,2127,2115],{"class":343},[298,2129,2130],{"class":339}," HISTFILESIZE",[298,2132,344],{"class":343},[298,2134,2135],{"class":324},"20000\n",[23,2137,2139],{"id":2138},"errores-frecuentes","Errores frecuentes",[28,2141,2142,2155],{},[31,2143,2144],{},[34,2145,2146,2149,2152],{},[37,2147,2148],{},"Síntoma",[37,2150,2151],{},"Causa",[37,2153,2154],{},"Solución",[55,2156,2157,2174,2191,2205,2225,2236,2252],{},[34,2158,2159,2166,2169],{},[60,2160,2161,2162,2165],{},"Edité ",[165,2163,2164],{},".zshrc"," y no pasa nada",[60,2167,2168],{},"no recargaste",[60,2170,2171],{},[165,2172,2173],{},"source ~\u002F.zshrc",[34,2175,2176,2182,2188],{},[60,2177,2178,2181],{},[165,2179,2180],{},"command not found"," después de instalar",[60,2183,532,2184,2187],{},[165,2185,2186],{},"PATH"," no incluye la carpeta",[60,2189,2190],{},"agregarlo al archivo de tu shell",[34,2192,2193,2196,2199],{},[60,2194,2195],{},"El script anda en bash y no en fish",[60,2197,2198],{},"sintaxis incompatible",[60,2200,2201,2202],{},"ejecutarlo con ",[165,2203,2204],{},"bash script.sh",[34,2206,2207,2215,2220],{},[60,2208,2209,2211,2212],{},[165,2210,265],{}," falla con ",[165,2213,2214],{},"[[ ]]",[60,2216,2217,2219],{},[165,2218,211],{}," no soporta esa sintaxis",[60,2221,2222,2223],{},"usar ",[165,2224,1347],{},[34,2226,2227,2230,2233],{},[60,2228,2229],{},"El prompt tarda segundos",[60,2231,2232],{},"plugin pesado",[60,2234,2235],{},"desactivar plugins y medir",[34,2237,2238,2243,2246],{},[60,2239,2240,2242],{},[165,2241,2186],{}," duplicado",[60,2244,2245],{},"el archivo se carga dos veces",[60,2247,2248,2249],{},"agregar guardas o revisar ",[165,2250,2251],{},".profile",[34,2253,2254,2260,2265],{},[60,2255,2256,2259],{},[165,2257,2258],{},"permission denied"," al cambiar shell",[60,2261,2262,2263],{},"el shell no está en ",[165,2264,1989],{},[60,2266,2267],{},"agregarlo o instalarlo",[23,2269,2271],{"id":2270},"qué-elegir","Qué elegir",[28,2273,2274,2284],{},[31,2275,2276],{},[34,2277,2278,2281],{},[37,2279,2280],{},"Situación",[37,2282,2283],{},"Elección",[55,2285,2286,2293,2300,2307],{},[34,2287,2288,2291],{},[60,2289,2290],{},"Vas a escribir scripts para servidores o proyectos",[60,2292,199],{},[34,2294,2295,2298],{},[60,2296,2297],{},"Quieres comodidad sin configurar",[60,2299,207],{},[34,2301,2302,2305],{},[60,2303,2304],{},"Quieres compatibilidad + plugins",[60,2306,203],{},[34,2308,2309,2312],{},[60,2310,2311],{},"No quieres pensar en nada",[60,2313,2314],{},"el que venga instalado",[14,2316,2317,2318,2320],{},"No hay una respuesta correcta: hay contexto. Lo que ",[18,2319,1202],{}," es universal es saber\nbash, porque es el que está en la máquina cuando algo se rompe.",[14,2322,2323,2324,212],{},"Siguiente parada: ",[1523,2325,2327],{"href":2326},"\u002Fvim","Vim",[2329,2330],"hr",{},[14,2332,2333],{},[2334,2335,2336],"em",{},"Hecho con amor para Laura, por Bogdan.",[2338,2339,2340],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":287,"searchDepth":308,"depth":308,"links":2342},[2343,2344,2351,2352,2353,2354,2355,2360,2361],{"id":25,"depth":308,"text":26},{"id":215,"depth":308,"text":216,"children":2345},[2346,2347,2348,2349,2350],{"id":273,"depth":314,"text":274},{"id":633,"depth":314,"text":634},{"id":943,"depth":314,"text":944},{"id":1078,"depth":314,"text":1079},{"id":1174,"depth":314,"text":1175},{"id":199,"depth":308,"text":43},{"id":203,"depth":308,"text":48},{"id":207,"depth":308,"text":53},{"id":1940,"depth":308,"text":1941},{"id":1993,"depth":308,"text":1994,"children":2356},[2357,2358,2359],{"id":2000,"depth":314,"text":2001},{"id":2053,"depth":314,"text":2054},{"id":2089,"depth":314,"text":2090},{"id":2138,"depth":308,"text":2139},{"id":2270,"depth":308,"text":2271},"Diferencias entre shells, archivos de configuración y cuál elegir.","md",{},"\u002Fshells",{"title":5,"description":2362},"kq36tT1vk4tMuQO0TMPzyM3teL4c2_EOeRJxZSQex2c",1793539815760]